Nginx is fast, but serving static content (images, CSS, JS) repeatedly from disk is inefficient. Caching static files in memory or enabling browser caching reduces load and speeds up response times.

This guide covers two types of caching with Nginx: browser caching and server‑side caching.

Prerequisites

A VPS running Ubuntu 24.04 with Nginx installed. Check our VPS reviews if you need one.

1. Browser Caching (Cache-Control Headers)

Browser caching tells the user's browser to store static files locally. The next time they visit, the browser loads files from cache instead of requesting them from the server.

Edit your Nginx site configuration:

sudo nano /etc/nginx/sites-available/example.com

Add this inside the server block:

location ~* \.(jpg|jpeg|png|gif|ico|svg|css|js|woff|woff2|ttf)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
    access_log off;
    log_not_found off;
}

Explanation:

  • expires 30d – Sets cache expiry to 30 days
  • Cache-Control "public, immutable" – Instructs browsers to cache and never re‑validate
  • access_log off – Skip logging static requests (reduces disk I/O)

Test and reload Nginx:

sudo nginx -t
sudo systemctl reload nginx

2. Server‑Side Caching (FastCGI Cache)

FastCGI cache stores dynamic PHP responses as static files. This reduces PHP processing time for repeat visits.

First, create a cache directory:

sudo mkdir -p /var/cache/nginx
sudo chown -R www-data:www-data /var/cache/nginx

Add this to the http block in /etc/nginx/nginx.conf:

fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=fastcgicache:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

In your site configuration, add FastCGI cache directives:

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;

    fastcgi_cache fastcgicache;
    fastcgi_cache_valid 200 301 302 10m;
    fastcgi_cache_use_stale error timeout updating http_500;
    fastcgi_cache_lock on;
    fastcgi_cache_lock_timeout 5s;

    # Skip cache for logged‑in users
    fastcgi_cache_bypass $cookie_user;
    fastcgi_no_cache $cookie_user;

    add_header X-Cache $upstream_cache_status;
}

The X-Cache header will show HIT or MISS in browser devtools.

3. Gzip Compression (Reduces Transfer Size)

Enable gzip to compress responses before sending to browsers:

In /etc/nginx/nginx.conf, add or uncomment:

gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml image/svg+xml;

4. Micro‑Caching for Dynamic Content

For sites that don't need real‑time updates, cache dynamic pages for 1-5 seconds:

fastcgi_cache_valid 200 5s;

This reduces server load during traffic spikes while keeping content fresh enough.

5. Testing Your Cache

Open browser devtools (F12) → Network tab. Reload your site. Look at the X-Cache header:

  • HIT – Cache is working
  • MISS – Not cached yet (may appear on first visit)
  • BYPASS – Cache skipped (for logged‑in users)

For static files, check the Cache-Control header. It should show max-age=2592000 (30 days).

6. Clearing Nginx Cache

To clear the FastCGI cache manually:

sudo rm -rf /var/cache/nginx/*

To clear browser cache for a specific file, use versioning (style.css?v=2).

7. Monitoring Cache Performance

Check cache hit ratio by viewing Nginx logs:

sudo tail -f /var/log/nginx/access.log

Look for HIT and MISS in the log output. Hit ratios above 80% indicate good cache performance.

Troubleshooting

Static files not cached – Check if the location block matches your file types. Test with curl -I https://example.com/style.css.

PHP pages always MISS – Check that FastCGI cache is enabled and the cache directory is writable: ls -la /var/cache/nginx.

Cache not clearing – If rm -rf doesn't work, check file permissions. You may need to stop Nginx temporarily.

Next Steps

With caching configured, run Google PageSpeed Insights. Your performance score should improve by 10‑20 points. Fine‑tune based on your site's traffic patterns.

Need a VPS to practice on? Check our recommended VPS providers.