Apache Compression Configuration Guide

Master mod_deflate and mod_brotli for optimal web performance

Quick Start: Enable Gzip with mod_deflate

Apache's mod_deflate module provides gzip compression. Here's how to enable it:

1. Enable mod_deflate

# Ubuntu/Debian
sudo a2enmod deflate
sudo systemctl restart apache2

# CentOS/RHEL
# mod_deflate is usually enabled by default
sudo systemctl restart httpd

# Verify module is loaded
apachectl -M | grep deflate

2. Basic .htaccess Configuration

<IfModule mod_deflate.c>
    # Compress HTML, CSS, JavaScript, Text, XML and fonts
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
    AddOutputFilterByType DEFLATE application/x-font
    AddOutputFilterByType DEFLATE application/x-font-opentype
    AddOutputFilterByType DEFLATE application/x-font-otf
    AddOutputFilterByType DEFLATE application/x-font-truetype
    AddOutputFilterByType DEFLATE application/x-font-ttf
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE font/opentype
    AddOutputFilterByType DEFLATE font/otf
    AddOutputFilterByType DEFLATE font/ttf
    AddOutputFilterByType DEFLATE image/svg+xml
    AddOutputFilterByType DEFLATE image/x-icon
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/xml
</IfModule>

Advanced mod_deflate Configuration

Optimize compression with advanced settings:

<IfModule mod_deflate.c>
    # Force compression for mangled headers
    <IfModule mod_setenvif.c>
        <IfModule mod_headers.c>
            SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
            RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
        </IfModule>
    </IfModule>

    # Compress all output labeled with one of the following MIME-types
    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE "application/atom+xml" \
                                      "application/javascript" \
                                      "application/json" \
                                      "application/ld+json" \
                                      "application/manifest+json" \
                                      "application/rdf+xml" \
                                      "application/rss+xml" \
                                      "application/schema+json" \
                                      "application/vnd.geo+json" \
                                      "application/vnd.ms-fontobject" \
                                      "application/x-font-ttf" \
                                      "application/x-javascript" \
                                      "application/x-web-app-manifest+json" \
                                      "application/xhtml+xml" \
                                      "application/xml" \
                                      "font/eot" \
                                      "font/opentype" \
                                      "image/bmp" \
                                      "image/svg+xml" \
                                      "image/vnd.microsoft.icon" \
                                      "image/x-icon" \
                                      "text/cache-manifest" \
                                      "text/css" \
                                      "text/html" \
                                      "text/javascript" \
                                      "text/plain" \
                                      "text/vcard" \
                                      "text/vnd.rim.location.xloc" \
                                      "text/vtt" \
                                      "text/x-component" \
                                      "text/x-cross-domain-policy" \
                                      "text/xml"
    </IfModule>

    # Set compression level (1-9, default is 6)
    DeflateCompressionLevel 6

    # Set compression window size (1-15, default is 15)
    DeflateWindowSize 15

    # Set compression memory level (1-9, default is 8)
    DeflateMemLevel 8

    # Remove browser bugs
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    Header append Vary User-Agent
</IfModule>

Enable Brotli Compression with mod_brotli

Apache 2.4.26+ supports Brotli compression through mod_brotli:

1. Install mod_brotli

# Ubuntu/Debian (Apache 2.4.26+)
sudo apt-get install apache2-bin
sudo a2enmod brotli
sudo systemctl restart apache2

# CentOS/RHEL 8+
sudo dnf install mod_brotli
sudo systemctl restart httpd

# Verify module
apachectl -M | grep brotli

2. Configure mod_brotli

<IfModule mod_brotli.c>
    # Enable Brotli compression
    AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css
    AddOutputFilterByType BROTLI_COMPRESS text/javascript application/javascript
    AddOutputFilterByType BROTLI_COMPRESS application/x-javascript application/json
    AddOutputFilterByType BROTLI_COMPRESS application/xml application/xhtml+xml
    AddOutputFilterByType BROTLI_COMPRESS application/rss+xml
    AddOutputFilterByType BROTLI_COMPRESS application/atom+xml
    AddOutputFilterByType BROTLI_COMPRESS application/x-font-ttf application/x-font-otf
    AddOutputFilterByType BROTLI_COMPRESS font/opentype font/truetype font/eot font/otf
    AddOutputFilterByType BROTLI_COMPRESS image/svg+xml image/x-icon

    # Compression level (0-11, default is 5)
    BrotliCompressionLevel 6

    # Window size (10-24, default is 22)
    BrotliWindowSize 22
</IfModule>

Complete Production Configuration

Use both gzip and Brotli for maximum compatibility:

httpd.conf / apache2.conf

# Load modules (if not already loaded)
LoadModule deflate_module modules/mod_deflate.so
LoadModule brotli_module modules/mod_brotli.so
LoadModule filter_module modules/mod_filter.so
LoadModule headers_module modules/mod_headers.so

# Global compression configuration
<IfModule mod_deflate.c>
    # Enable compression
    SetOutputFilter DEFLATE
    
    # Don't compress images
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|ico|zip|gz|bz2|rar|7z)$ no-gzip dont-vary
    
    # Set compression level
    DeflateCompressionLevel 6
    
    # Handle proxies correctly
    Header append Vary Accept-Encoding
</IfModule>

<IfModule mod_brotli.c>
    # Enable Brotli for supported types
    SetOutputFilter BROTLI_COMPRESS
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|ico|zip|gz|br|bz2|rar|7z)$ no-br
    
    # Brotli compression level
    BrotliCompressionLevel 6
</IfModule>

VirtualHost Configuration

<VirtualHost *:443>
    ServerName example.com
    DocumentRoot /var/www/html
    
    # SSL Configuration (required for Brotli in browsers)
    SSLEngine on
    SSLCertificateFile /path/to/cert.pem
    SSLCertificateKeyFile /path/to/key.pem
    
    # Compression settings
    <Directory /var/www/html>
        <IfModule mod_deflate.c>
            AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
            AddOutputFilterByType DEFLATE application/javascript application/json
            AddOutputFilterByType DEFLATE application/xml+rss application/xhtml+xml
            AddOutputFilterByType DEFLATE font/opentype font/truetype
            AddOutputFilterByType DEFLATE image/svg+xml image/x-icon
        </IfModule>
        
        <IfModule mod_brotli.c>
            AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css
            AddOutputFilterByType BROTLI_COMPRESS application/javascript application/json
            AddOutputFilterByType BROTLI_COMPRESS application/xml+rss application/xhtml+xml
            AddOutputFilterByType BROTLI_COMPRESS font/opentype font/truetype
            AddOutputFilterByType BROTLI_COMPRESS image/svg+xml image/x-icon
        </IfModule>
    </Directory>
    
    # Pre-compressed file support
    <FilesMatch "\.(js|css|html|xml|json)$">
        <IfModule mod_headers.c>
            Header append Vary Accept-Encoding
        </IfModule>
    </FilesMatch>
    
    # Serve pre-compressed files if they exist
    RewriteEngine On
    
    # Serve Brotli compressed files
    RewriteCond %{HTTP:Accept-Encoding} br
    RewriteCond %{REQUEST_FILENAME}.br -f
    RewriteRule ^(.*)$ $1.br [L]
    
    # Serve gzip compressed files
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteCond %{REQUEST_FILENAME}.gz -f
    RewriteRule ^(.*)$ $1.gz [L]
    
    # Set correct content types for compressed files
    <FilesMatch "\.js\.br$">
        Header set Content-Type "application/javascript"
        Header set Content-Encoding "br"
    </FilesMatch>
    
    <FilesMatch "\.css\.br$">
        Header set Content-Type "text/css"
        Header set Content-Encoding "br"
    </FilesMatch>
    
    <FilesMatch "\.html\.br$">
        Header set Content-Type "text/html"
        Header set Content-Encoding "br"
    </FilesMatch>
    
    <FilesMatch "\.js\.gz$">
        Header set Content-Type "application/javascript"
        Header set Content-Encoding "gzip"
    </FilesMatch>
    
    <FilesMatch "\.css\.gz$">
        Header set Content-Type "text/css"
        Header set Content-Encoding "gzip"
    </FilesMatch>
    
    <FilesMatch "\.html\.gz$">
        Header set Content-Type "text/html"
        Header set Content-Encoding "gzip"
    </FilesMatch>
</VirtualHost>

Compression by File Type

Optimize compression settings for different content types:

HTML/XML Files

<FilesMatch "\.(html|htm|xml|xhtml)$">
    <IfModule mod_deflate.c>
        SetOutputFilter DEFLATE
        DeflateCompressionLevel 9
    </IfModule>
    <IfModule mod_brotli.c>
        SetOutputFilter BROTLI_COMPRESS
        BrotliCompressionLevel 11
    </IfModule>
</FilesMatch>

CSS/JavaScript Files

<FilesMatch "\.(css|js)$">
    <IfModule mod_deflate.c>
        SetOutputFilter DEFLATE
        DeflateCompressionLevel 9
    </IfModule>
    <IfModule mod_brotli.c>
        SetOutputFilter BROTLI_COMPRESS
        BrotliCompressionLevel 11
    </IfModule>
    
    # Long cache for static assets
    <IfModule mod_expires.c>
        ExpiresActive On
        ExpiresDefault "access plus 1 year"
    </IfModule>
</FilesMatch>

API/JSON Responses

<Location /api>
    <IfModule mod_deflate.c>
        SetOutputFilter DEFLATE
        DeflateCompressionLevel 1
    </IfModule>
    <IfModule mod_brotli.c>
        SetOutputFilter BROTLI_COMPRESS
        BrotliCompressionLevel 1
    </IfModule>
</Location>

Testing Compression

Verify your compression configuration is working:

Using curl

# Test gzip compression
curl -H "Accept-Encoding: gzip" -I https://example.com/style.css

# Test Brotli compression
curl -H "Accept-Encoding: br" -I https://example.com/style.css

# Check response headers for:
# Content-Encoding: gzip
# Content-Encoding: br
# Vary: Accept-Encoding

Apache Server Status

# Enable server status module
sudo a2enmod status

# Add to configuration
<Location "/server-status">
    SetHandler server-status
    Require ip 127.0.0.1
</Location>

# View compression statistics
curl http://localhost/server-status?auto | grep -i compress

Performance Tuning

Memory Usage

Each compression stream uses memory:

  • DeflateMemLevel: 1-9 (default 8)
  • Lower = less memory, less compression
  • Monitor with: top -p $(pgrep httpd)

CPU Optimization

Balance compression with CPU usage:

  • Dynamic content: Level 1-4
  • Static content: Level 6-9
  • Use pre-compressed for best performance

Buffer Sizes

Tune buffers for your workload:

DeflateBufferSize 8192
BrotliCompressionMaxInputBlock 16384

Troubleshooting Common Issues

Compression Not Working

  • Check if modules are loaded: apachectl -M | grep -E '(deflate|brotli)'
  • Verify .htaccess is allowed: AllowOverride All
  • Check error logs: tail -f /var/log/apache2/error.log
  • Ensure MIME types are correct

Double Compression

Prevent compressing already compressed content:

# Skip compression for already compressed formats
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|zip|gz|br|bz2|7z|mp4|webm)$ no-gzip dont-vary

Proxy Issues

Handle proxied requests correctly:

<IfModule mod_deflate.c>
    # Always send Vary header
    Header append Vary Accept-Encoding
    
    # Handle proxy headers
    SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding) .* HAVE_Accept-Encoding
    RequestHeader append Accept-Encoding "gzip,deflate,br" env=HAVE_Accept-Encoding
</IfModule>