Understanding Nginx Caching
Nginx's proxy_cache module lets it store a copy of an upstream response so that subsequent identical requests can be served directly from that stored copy instead of round-tripping to the backend application every single time. This matters because most web traffic is heavily skewed toward a small set of popular URLs, and regenerating the same response thousands of times per minute wastes CPU, database connections, and latency budget that caching can eliminate almost entirely.
Cricket analogy: When Virat Kohli walks out to bat, commentators reuse a pre-built stats graphic instead of recalculating his career average from scratch each over; Nginx's proxy cache does the same, serving a stored response instead of re-querying the backend for every request.
Configuring proxy_cache
The proxy_cache_path directive, set in the http block, defines everything about where and how cached data is stored: the disk directory, a levels parameter that splits the cache into subdirectories for fast lookups, a keys_zone that names an in-memory area tracking metadata, a max_size cap on total disk usage, and an inactive window controlling how long unused entries are kept before eviction. Once that zone exists, applying proxy_cache my_cache; inside a location block turns caching on for matching requests.
Cricket analogy: Setting up proxy_cache_path is like the groundstaff marking out designated storage bays for the covers and rollers at Lord's — levels=1:2 defines the folder structure, keys_zone names the shared memory 'storeroom', and max_size caps how much gear can be kept before the oldest is cleared.
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m
max_size=1g inactive=60m use_temp_path=off;
server {
listen 80;
location / {
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_bypass $http_cache_control;
proxy_cache_key $scheme$proxy_host$request_uri;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}
}
}Cache Keys and Bypass Rules
The cache key is what Nginx uses to decide whether two requests are 'the same' response — by default it's built from $scheme, $proxy_host, and $request_uri, meaning two requests differing only in a query parameter are treated as separate cache entries unless you customize proxy_cache_key. proxy_cache_bypass and proxy_no_cache give finer control: the former skips reading from cache under a condition, the latter skips writing a response into the cache at all, both commonly triggered by cookies or headers that indicate personalized content.
Cricket analogy: The default cache key $scheme$proxy_host$request_uri is like an umpire distinguishing deliveries by format, venue, and over number — two requests differing only in query string are treated as separate 'balls bowled' unless you explicitly fold query params into the key.
The $upstream_cache_status variable (HIT, MISS, BYPASS, EXPIRED, STALE) is invaluable for debugging cache behavior — add it as a response header with add_header X-Cache-Status $upstream_cache_status; during troubleshooting.
Cache Purging and Invalidation
Open-source Nginx does not ship a native cache purge API, so teams typically fall back on one of several strategies: short proxy_cache_valid windows that let stale content expire naturally, versioned asset URLs that force a new cache key on deploy, the third-party ngx_cache_purge module that adds an explicit PURGE method, or origin-controlled X-Accel-Expires headers that let the backend dictate freshness per response. Choosing the right strategy depends on how often content actually changes and how tolerant the application is of briefly serving stale data.
Cricket analogy: Since stock Nginx lacks a native purge command, teams often rely on short proxy_cache_valid windows, much like a scoreboard operator who just lets the display auto-refresh every few overs rather than manually correcting every stale number.
Never cache responses containing Set-Cookie headers or authenticated content by default — proxy_cache automatically skips these, but explicitly setting proxy_ignore_headers or misconfiguring proxy_cache_key can leak one user's private data to another.
- proxy_cache_path defines where and how cached responses are stored, including size limits and directory structure.
- The cache key determines which requests are treated as identical — include enough variables to avoid serving the wrong content to the wrong client.
- proxy_cache_valid sets how long different response codes stay cached before being considered stale.
- Stock Nginx lacks a native cache purge command; use the ngx_cache_purge module, versioned URLs, or short TTLs instead.
- Never cache responses containing session cookies or private user data without explicit safeguards.
- $upstream_cache_status is the primary tool for debugging whether requests are hitting or missing the cache.
- proxy_cache_bypass and proxy_no_cache give fine-grained control over which requests skip the cache entirely.
Practice what you learned
1. Which directive defines the shared memory zone and disk location used for Nginx's proxy cache?
2. What does the $upstream_cache_status variable indicate?
3. Why does stock open-source Nginx not support purging a cached entry directly by API call?
4. Which directive prevents Nginx from caching a response that contains sensitive per-user data, such as one with a Set-Cookie header?
5. In proxy_cache_path ... max_size=1g inactive=60m;, what does inactive=60m control?
Was this page helpful?
You May Also Like
Gzip and Compression
How Nginx's gzip module shrinks response payloads, the directives that control it, and how Brotli compares as a modern alternative.
Connection and Buffer Tuning
How worker, connection, and buffer settings determine Nginx's throughput ceiling, and how to tune them safely for high-concurrency workloads.
Nginx Performance Benchmarking
How to rigorously measure Nginx throughput and latency with tools like ab and wrk, interpret latency percentiles, and avoid common benchmarking pitfalls.
Related Reading
Related Study Notes in DevOps
Browse all study notesAnsible Study Notes
DevOps · 30 topics
DevOpsAdvanced Kubernetes Study Notes
Kubernetes · 30 topics
DevOpsAdvanced Bash Scripting Study Notes
Bash · 30 topics
DevOpsApache Kafka Study Notes
Kafka · 30 topics
DevOpsDocker & Kubernetes Study Notes
YAML · 40 topics
DevOpsCI/CD Tools & Pipelines Study Notes
YAML · 37 topics