100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
DevOps

Nginx Caching Explained

How Nginx's proxy_cache module stores upstream responses to cut backend load and speed up delivery, and how to configure, key, and invalidate that cache correctly.

Performance & CachingIntermediate10 min readJul 10, 2026
Analogies

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.

nginx
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

Was this page helpful?

Topics covered

#DevOps#NginxStudyNotes#NginxCachingExplained#Nginx#Caching#Explained#Configuring#StudyNotes#SkillVeris#ExamPrep