NewHalo Edge 3 is here: HTTP/3 everywhere and 42 edge locations.Learn more
Docs / Web servers

Enable compression and browser caching

Web servers6 min readUbuntu 24.04 LTS

Compression shrinks text files such as HTML, CSS and JavaScript before they are sent, and caching headers let browsers reuse files they have already downloaded. Together they make pages load faster, using only a few lines of nginx configuration.

Before you begin

  • nginx serving a website. See Install and configure nginx.
  • A sudo user, such as deploy, and some static files such as CSS, JavaScript or images in your site folder.

Step 1: Check the existing gzip settings

Ubuntu's default nginx.conf already enables gzip compression, sometimes with lines commented out. Search for existing settings before you add new ones. Duplicate directives stop nginx from starting, so you will edit lines rather than add copies.

sudo grep -rn "gzip" /etc/nginx/

Step 2: Set the compression options

Open the main configuration with sudo nano /etc/nginx/nginx.conf and find the http block. If a line is commented out with a leading #, remove the # and adjust the value. Make the block match these settings:

gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml;

HTML is always compressed when gzip is on, so you do not need to list text/html. gzip_comp_level trades CPU time for size, and 5 is a sensible middle value. gzip_min_length skips files too small to benefit.

Step 3: Add caching for static files

Static files rarely change between visits, so browsers can keep them. Inside the server block of your site file, add a location block that matches common file extensions. The expires directive makes nginx send a Cache-Control header with a maximum age of 30 days.

location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff2)$ {
    expires 30d;
    access_log off;
}
Careful: A long cache time means visitors may keep an old copy of a file after you change it. Use versioned file names, such as style.v2.css, when you update assets, or choose a shorter time.

Step 4: Test and reload

Check the configuration and reload nginx.

sudo nginx -t
sudo systemctl reload nginx
nginx: configuration file /etc/nginx/nginx.conf test is successful

Step 5: Verify compression

Ask for the page while saying your client accepts gzip. The response should include Content-Encoding: gzip. Replace the domain with your own.

curl -sI -H "Accept-Encoding: gzip" https://example.com/ | grep -i content-encoding
content-encoding: gzip

If the header is missing, the page may be smaller than gzip_min_length, or its type may be missing from gzip_types.

Step 6: Verify caching

Request a static file and look for the cache header. Use a CSS file that exists on your site.

curl -sI https://example.com/style.css | grep -i cache-control
cache-control: max-age=2592000

The value 2592000 is 30 days in seconds. Browsers will reuse the cached copy until it expires.

Step 7: Apache equivalent

On Apache, enable the modules with sudo a2enmod deflate expires, then reload with sudo systemctl reload apache2. Add these lines inside your site's VirtualHost block:

<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType text/css "access plus 30 days"
    ExpiresByType application/javascript "access plus 30 days"
    ExpiresByType image/png "access plus 30 days"
</IfModule>
AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json

Troubleshooting

  • nginx -t reports a duplicate directive. You have two copies of a gzip line. Keep one and delete the other, then test again.
  • No content-encoding header. The response is smaller than gzip_min_length, the client did not send Accept-Encoding, or the file type is not listed in gzip_types.
  • Visitors still see old CSS or JavaScript. Their browsers are using a cached copy. Rename the file, or lower the expires value and wait for the old cache to expire.
  • No cache-control header on a file. The file extension is not in the regular expression, or the location block sits outside the right server block.

Next steps

Compression and caching work best on a site that is already secure and redirects to one address. Finish those with Redirect HTTP to HTTPS and www to non-www, and if you run an application behind nginx, see Set up an nginx reverse proxy.

Something not working? Chat or email our support team and we will help you get unstuck.

Contact support