Proxy caching in Nginx reduces upstream load and response time by serving repeat requests from local storage instead of regenerating content on every hit. It is most effective for anonymous traffic and cache-safe API endpoints where the same response can be reused across multiple clients.

In Nginx, proxy_cache_path defines where cached responses are stored on disk and allocates shared memory (keys_zone) for cache keys and metadata. When a server or location enables proxy_cache, eligible upstream responses are stored under a cache key and served until they expire, while $upstream_cache_status exposes whether a request was a cache HIT or MISS.

Caching correctness depends on response variability and cache controls. Endpoints that vary by user, cookies, Authorization, locale, or content encoding can leak data or serve incorrect content if cached without explicit bypass rules and cache keys. Configuration placement also matters: proxy_cache_path must live in the http context (commonly /etc/nginx/nginx.conf), and the cache directory must be writable by the Nginx worker user.

Steps to enable caching in Nginx:

  1. Create the on-disk cache directory used by proxy_cache_path.
    $ sudo install --directory --mode=0750 --owner=www-data --group=www-data /var/cache/nginx

    On many distros the Nginx worker user is nginx instead of www-data.

  2. Add a proxy_cache_path definition inside the http block.
    http {
        proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=static_cache:100m max_size=5g inactive=60m use_temp_path=off;
        ##### snipped #####
    }

    keys_zone=static_cache:100m names the cache and reserves shared memory for cache metadata, while inactive=60m controls how long unused items stay on disk.

  3. Enable proxy_cache in the proxied location inside the site server block.
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_cache static_cache;
        proxy_cache_valid 200 301 302 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_bypass $http_authorization;
        proxy_no_cache $http_authorization;
        add_header X-Cache-Status $upstream_cache_status always;
    }

    Do not cache responses that are user-specific, contain Set-Cookie, or rely on Authorization unless cache keys and bypass rules are designed for it.

  4. Validate the Nginx configuration syntax.
    $ sudo nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
  5. Reload Nginx to apply the cache configuration.
    $ sudo systemctl reload nginx
  6. Confirm caching using the X-Cache-Status header on repeated requests.
    $ curl --head --silent http://127.0.0.1/ | grep --ignore-case '^x-cache-status:'
    X-Cache-Status: MISS
    $ curl --head --silent http://127.0.0.1/ | grep --ignore-case '^x-cache-status:'
    X-Cache-Status: HIT

    Common values include MISS, HIT, BYPASS, EXPIRED, and UPDATING.

Discuss the article:

Comment anonymously. Login not required.