Nginx Caching Headers Configuration

Configure browser caching headers in Nginx using expires and Cache-Control directives to optimize static asset delivery and reduce overall server load.

Performance

Detailed Explanation

Caching headers instruct browsers and intermediate proxies on how long to store responses locally, eliminating redundant network requests and dramatically improving page load performance for returning visitors.

Expires Directive

The expires directive sets both the Expires and Cache-Control: max-age headers simultaneously. Use it for static assets that change infrequently to maximize cache hit rates.

location ~* \.(jpg|jpeg|png|gif|ico|svg)$ {
    expires 30d;
    add_header Cache-Control "public, no-transform";
}

location ~* \.(css|js)$ {
    expires 7d;
    add_header Cache-Control "public, no-transform";
}

location ~* \.(woff|woff2|ttf|otf|eot)$ {
    expires 365d;
    add_header Cache-Control "public, immutable";
}

Cache-Control Header

For finer control over caching behavior, use the add_header Cache-Control directive directly. Common values include:

  • public: Response can be cached by any cache, including browsers, CDNs, and proxy servers.
  • private: Response is specific to one user and should only be cached by the browser, not shared caches.
  • no-cache: The cache must revalidate with the origin server before using a stored response.
  • no-store: Response must never be stored in any cache, suitable for sensitive data.
  • immutable: Tells the browser the resource will never change during its max-age lifetime, preventing conditional revalidation requests.

ETag and Last-Modified

Nginx automatically sends ETag and Last-Modified headers for static files served from disk. These enable conditional requests where the browser sends If-None-Match or If-Modified-Since headers, and Nginx can return a lightweight 304 Not Modified response if the file has not changed, saving bandwidth.

Proxy Cache

For dynamic content generated by backend applications, Nginx can cache upstream responses using the proxy_cache directive. Define a cache zone in the http block and activate it within your location block:

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=app_cache:10m max_size=1g inactive=60m;

location / {
    proxy_cache app_cache;
    proxy_cache_valid 200 10m;
    proxy_cache_valid 404 1m;
}

Cache Busting Strategy

Use filename hashing (e.g., style.a3b4c5.css) for versioned assets in your build pipeline. This allows aggressive caching with long expiration times while guaranteeing users always receive the latest version after each deployment.

Use Case

You need to set appropriate cache lifetimes for different asset types so returning visitors experience instant page loads while still receiving updated content when it changes.

Try It — Nginx Config Generator

Open full tool