A reverse proxy cache stores responses from your application server and serves them directly for repeat requests — dramatically reducing load on your backend for content that doesn't need to be regenerated on every request.
What This Solves
Many pages/responses are identical for many visitors (product listings, blog posts, API responses that don't change per-user) — regenerating them from scratch on every request wastes CPU/database resources that caching can eliminate entirely.
Basic Nginx proxy_cache Configuration
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m;
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_cache my_cache;
proxy_cache_valid 200 10m;
proxy_cache_valid 404 1m;
add_header X-Cache-Status $upstream_cache_status;
}
}
}
proxy_cache_path defines where cached responses are stored and how much space they can use; proxy_cache_valid sets how long different response codes stay cached.
Understanding the X-Cache-Status Header
curl -I https://yourdomain.com
Values include HIT (served from cache), MISS (fetched fresh from backend), and BYPASS (caching deliberately skipped) — useful for verifying caching is actually working as expected.
Excluding Dynamic/Personalized Content from Caching
location /api/user-specific {
proxy_pass http://backend;
proxy_cache_bypass 1;
proxy_no_cache 1;
}
Critical: never cache responses containing personalized data (account info, cart contents) unless properly keyed per-user — caching one user's personalized response and serving it to another is a serious data leak.
Caching Based on Query String Variations Correctly
proxy_cache_key "$scheme$request_method$host$request_uri";
By default, different query strings produce different cache entries — verify this is the behavior you actually want, since unbounded query string variation can fill your cache with many rarely-reused entries.
Setting Cache Duration Based on Content Type
location ~* \.(jpg|jpeg|png|css|js)$ {
proxy_pass http://backend;
proxy_cache my_cache;
proxy_cache_valid 200 7d;
}
location / {
proxy_pass http://backend;
proxy_cache my_cache;
proxy_cache_valid 200 5m;
}
Static assets can safely cache much longer than dynamic HTML pages.
Purging the Cache When Content Changes
rm -rf /var/cache/nginx/*
A blunt approach that clears everything; for more granular purging of specific URLs, additional Nginx modules or cache-key-based purging logic may be needed depending on your specific requirements.
Monitoring Cache Hit Ratio
Track the proportion of HIT vs MISS responses over time (via log analysis or the X-Cache-Status header fed into your monitoring stack) — a low hit ratio suggests your cache configuration or duration settings need adjustment.
When Reverse Proxy Caching Isn't Appropriate
Highly personalized applications (dashboards showing user-specific real-time data) generally aren't good candidates for full-page caching — object/data-level caching (see Redis-based caching guides) is often more appropriate there instead.
Common Errors
Cached response served to the wrong user — a serious bug indicating personalized content was accidentally cached; immediately review and fix the cache configuration to exclude that path.
Continue Reading
- How to Optimize a VPS for High-Traffic E-commerce
- Nginx Performance Tuning: Worker Processes, Caching & Gzip
- How to Set Up a CDN in Front of Your VPS
Browse more articles in Web Servers.