How to Configure Apache Mod_deflate, Mod_brotli, and Mod_expires for HTTP Compression and Browser Cache Control on Ubuntu Server

Learning how to configure Apache Mod_deflate, Mod_brotli, and Mod_expires for HTTP compression and browser cache control on Ubuntu Server is one of the best performance upgrades you can make for any website. These three Apache modules work together to compress outgoing content and tell browsers how long to cache static files. The result is faster page loads, lower bandwidth usage, and a better experience for your visitors. In this tutorial, you’ll enable and configure all three modules on Ubuntu Server. You’ll set up Gzip compression with Mod_deflate, add Brotli compression with Mod_brotli, and control browser caching with Mod_expires. By the end, your Apache server will serve compressed, cache-optimized responses to every client that supports them.

Prerequisites for Configuring Apache HTTP Compression and Cache Control

Before you start, make sure you have the following in place.

Required access and software:

  • Ubuntu Server 20.04 or 22.04 (fresh or existing install)
  • Apache 2.4 installed and running
  • Root or sudo access to the server
  • A basic understanding of the Linux command line
  • SSH access to your server

Estimated time: 20–30 minutes.

You should already have Apache installed. If you don’t, run sudo apt install apache2 -y before continuing. This tutorial assumes Apache is serving at least one virtual host. The steps below apply whether you’re running a WordPress site, a static site, or any other web application. Check that Apache is active before you begin.

sudo systemctl status apache2

You should see active (running) in the output. If Apache isn’t running, start it with sudo systemctl start apache2.

Step-by-Step Guide to Configure Apache Mod_deflate, Mod_brotli, and Mod_expires

See also: How to Configure Haproxy Rate Limiting with Stick Tables and Acls on Ubuntu

Follow these steps carefully. Each step builds on the last.

Step 1: Enable the required Apache modules

Apache ships with Mod_deflate and Mod_expires built in. Mod_brotli requires an extra package on Ubuntu. Run the following commands to install it and enable all three modules.

sudo apt update
sudo apt install brotli libapache2-mod-brotli -y
sudo a2enmod deflate
sudo a2enmod brotli
sudo a2enmod expires
sudo a2enmod headers
sudo systemctl restart apache2

The headers module is needed for setting cache-control headers later. Enabling it now saves you a second restart.

Step 2: Open your Apache configuration file

You can add compression and cache settings to your main Apache config or to a virtual host file. For a global setup, edit the main config directly.

sudo nano /etc/apache2/apache2.conf

Scroll to the bottom of the file. You’ll add your configuration blocks there.

Step 3: Configure Mod_deflate for Gzip compression

Paste the following block at the bottom of apache2.conf. This tells Apache to compress common file types before sending them to the browser.

# Enable Gzip compression with mod_deflate

    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE image/svg+xml
    AddOutputFilterByType DEFLATE font/woff2

    # Don't compress already-compressed files
    SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png|zip|gz|bz2|rar)$ no-gzip dont-vary

    # Add Vary header for proxies
    Header append Vary Accept-Encoding

The SetEnvIfNoCase line prevents Apache from trying to compress files that are already compressed. That would waste CPU cycles and could corrupt the response.

Step 4: Configure Mod_brotli for Brotli compression

Brotli typically achieves better compression than Gzip. Modern browsers support it. Add this block directly below the Deflate block.

# Enable Brotli compression with mod_brotli

    AddOutputFilterByType BROTLI_COMPRESS text/html
    AddOutputFilterByType BROTLI_COMPRESS text/plain
    AddOutputFilterByType BROTLI_COMPRESS text/xml
    AddOutputFilterByType BROTLI_COMPRESS text/css
    AddOutputFilterByType BROTLI_COMPRESS application/javascript
    AddOutputFilterByType BROTLI_COMPRESS application/json
    AddOutputFilterByType BROTLI_COMPRESS application/xml
    AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
    AddOutputFilterByType BROTLI_COMPRESS font/woff2

    BrotliCompressionQuality 6

A quality setting of 6 is a solid balance between compression ratio and CPU usage. You can raise it to 11 for maximum compression, but that increases server load. See the official Apache Mod_brotli documentation for all available directives.

Step 5: Configure Mod_expires for browser cache control

This block sets expiry times for different file types. Browsers will cache these files locally and won’t re-download them on repeat visits.

# Browser cache control with mod_expires

    ExpiresActive On

    # Images
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    ExpiresByType image/x-icon "access plus 1 year"

    # Fonts
    ExpiresByType font/woff2 "access plus 1 year"
    ExpiresByType font/woff "access plus 1 year"

    # CSS and JavaScript
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"

    # HTML
    ExpiresByType text/html "access plus 1 hour"

    # Default
    ExpiresDefault "access plus 1 week"

Images and fonts rarely change, so a one-year cache is safe. CSS and JavaScript change more often, so one month is more appropriate. HTML should have a short cache time to ensure users always see fresh content.

Step 6: Test the configuration and restart Apache

Before restarting, always test your Apache config for syntax errors.

sudo apachectl configtest

You should see Syntax OK. If you see any errors, go back and check your configuration blocks for typos. Once the test passes, restart Apache.

sudo systemctl restart apache2

Step 7: Verify compression and caching are working

Use curl to check that compression headers are present in the response.

curl -H "Accept-Encoding: br, gzip" -I http://yourdomain.com

Look for Content-Encoding: br or Content-Encoding: gzip in the output. Also check for Expires and Cache-Control headers. You can also use the Google PageSpeed Insights tool to confirm your server is sending compressed, cached responses correctly.

Troubleshooting Common Apache Compression and Caching Issues

Brotli module not found after install: Run sudo a2enmod brotli again and check that the package installed without errors. Run sudo apache2ctl -M | grep brotli to confirm it’s loaded.

Compression not showing in headers: Make sure the mod_headers module is enabled. Run sudo a2enmod headers and restart Apache. Also confirm the file type you’re testing is listed in your AddOutputFilterByType directives.

Cache headers missing: Check that ExpiresActive On is inside the block. A missing directive here will silently disable the whole block.

Config test fails with “Invalid command”: This usually means a module isn’t enabled. Double-check that you ran all the a2enmod commands in Step 1.

Brotli and Deflate both firing: Apache negotiates based on the client’s Accept-Encoding header. Modern browsers prefer Brotli. Older browsers fall back to Gzip. This is expected behavior.

Similar Posts