When caching is enabled, Nginx saves responses in a disk cache and uses them to respond to clients without having to proxy requests for the same content every time.[reference:13]
This guide covers two types of caching with Nginx: browser caching (Cache‑Control headers) and server‑side caching (proxy_cache).
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.[reference:14]
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;
}
What this does:
expires 30d– Sets cache expiry to 30 daysCache-Control "public, immutable"– Instructs browsers to cache and never re‑validateaccess_log off– Skips logging static requests (reduces disk I/O)
Test and reload Nginx:
sudo nginx -t
sudo systemctl reload nginx
2. Enable Gzip Compression
Compress files before sending them to browsers. This reduces transfer size and speeds up load times.
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;
With compression enabled, file sizes can shrink by 50% or more.
3. Server‑Side Caching (proxy_cache)
To enable caching, include the proxy_cache_path directive in the top‑level http {} context. The mandatory first parameter is the local filesystem path for cached content, and the mandatory keys_zone parameter defines the name and size of the shared memory zone used to store metadata about cached items.[reference:15]
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:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:100m max_size=10g inactive=60m;
proxy_cache_key "$scheme$request_method$host$request_uri";
In your site configuration, add proxy cache directives:
location / {
proxy_cache mycache;
proxy_cache_valid 200 301 302 10m;
proxy_cache_use_stale error timeout updating http_500;
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
proxy_pass http://localhost:8000;
}
The proxy_cache_valid directive defines how long to cache responses with different status codes.[reference:16]
4. Micro‑Caching for Dynamic Content
For sites that don't need real‑time updates, cache dynamic pages for 1‑5 seconds:
proxy_cache_valid 200 5s;
This reduces server load during traffic spikes while keeping content fresh enough.
5. How to Verify Cache is Working
Open browser developer tools (F12) → Network tab. Reload your page. Check the response headers:
- For static files, look for
Cache-Control: max-age=2592000 - For server‑side cache, add
add_header X-Cache $upstream_cache_status;to seeHITorMISS
6. Clearing Cache When You Update Content
After updating a CSS or JS file, users may still see the old version. Solutions:
- Rename the file (
style.css→style.v2.css) - Add a query parameter (
style.css?ver=2.0) - Clear Nginx cache manually:
sudo rm -rf /var/cache/nginx/*
Nginx makes it possible to remove outdated cached files to prevent serving old and new versions of web pages at the same time.[reference:17]
Troubleshooting
Static files not cached – Check if the location block matches your file types. Test with curl -I https://example.com/style.css.
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 or GTmetrix. Your performance score should improve by 10‑20 points.
Need a VPS to practice on? Check our recommended VPS providers.