Master Nginx Caching: Boost Performance with Client & Server Cache Strategies
This guide explains how Nginx implements both client‑side (browser) and server‑side (proxy) caching, details strong and conditional caching mechanisms, and provides practical configuration examples and code snippets to optimize cache behavior and improve web performance.
Nginx Detailed Usage – Caching
Nginx is a powerful web server and reverse proxy that can be used to implement static content caching, which includes client‑side caching and server‑side caching.
Client Cache
Client cache refers to the browser cache, which is the fastest because it retrieves resources locally (though it may send a conditional request). Its advantage is reducing network traffic and speeding up requests.
Server‑side cache refers to the reverse‑proxy or CDN cache, which reduces the load on the actual backend web server.
Browser cache can operate in two modes: strong cache and conditional cache.
Strong cache (no HTTP request, no negotiation)
The browser reads the local cache directly without contacting the server. HTTP status is 200 (from memory or disk cache, depending on the browser).
Relevant HTTP headers:
Cache-Control Expires
Conditional cache (HTTP request, negotiation required)
The browser finds a local copy but it is expired, so it asks the server whether the cached content is still valid. If the server deems the cached content usable, it returns 304 (Not Modified) and the browser reads the local cache; otherwise, the server returns the fresh resource.
Implementing client cache typically involves controlling HTTP response headers. Common methods include:
Cache-Control header: set max-age to specify the resource's lifetime in seconds. Cache-Control: max-age=3600 This example sets a 1‑hour cache duration.
Expires header: specify an absolute expiration date. Expires: Tue, 01 Jan 2025 00:00:00 GMT This example sets the expiration to January 1 2025.
Last-Modified and If-Modified-Since headers: the server sends Last-Modified indicating the resource's last modification time; the client later sends If-Modified-Since. If unchanged, the server returns 304.
Last-Modified: Mon, 01 Jan 2022 00:00:00 GMT If-Modified-Since: Mon, 01 Jan 2022 00:00:00 GMTETag and If-None-Match headers: the server provides an ETag identifier; the client returns it via If-None-Match. If unchanged, the server returns 304.
ETag: "abc123" If-None-Match: "abc123"Cache validation flow: browsers first check the strong cache expiration; if expired, they perform conditional validation using the above headers.
Server Cache
Proxy cache is a server‑side cache implemented by Nginx. When Nginx receives a response from the upstream server, it forwards the data to the client and simultaneously stores it on local disk according to the proxy cache configuration. Subsequent requests for the same resource are served directly from disk, reducing upstream latency.
Enable Nginx Cache
proxy_cache_path /tmp/nginx/cache levels=1:2 inactive=60s keys_zone=mycache:10m max_size=10g;Explanation of parameters:
/tmp/nginx/cache : cache file storage path.
levels : two‑level directory hierarchy (e.g., 1‑hex digit + 2‑hex digits) to improve lookup performance.
keys_zone : shared memory zone for cache keys (e.g., mycache:10m can store ~80 000 keys).
max_size : maximum cache size (optional, defaults to using all available disk space).
inactive : time after which unused cached files are removed (default 10 minutes; here set to 60 seconds).
Reference the cache in http, server or location blocks:
user nginx;
events {}
http {
proxy_cache_path /tmp/nginx/cache levels=1:2 keys_zone=mycache:10m max_size=10g;
server {
listen 80;
location /cache {
proxy_pass http://192.168.1.135:8080;
proxy_cache mycache;
add_header cache $upstream_cache_status; # optional, for testing
}
}
}Upstream Server Configuration
The upstream server must provide caching directives such as X-Accel-Expires, Expires, or Cache-Control: max-age= so that Nginx knows how long to cache the response.
server {
listen 8080;
location /cache {
add_header X-Accel-Expires 100; # notify proxy cache for 100 s
expires 50; # alternative way to set 50 s
add_header Cache-Control "max-age=50"; # another way
alias /www/html/docs/;
}
}Cache Status
The variable $upstream_cache_status can be MISS, HIT, EXPIRED, UPDATING, STALE, BYPASS, or REVALIDATED, indicating how the request was handled.
Controlling Cache Usage
Use proxy_cache_bypass to skip cache when certain query parameters are present (e.g., nocache or comment), and proxy_no_cache to prevent caching under specified conditions.
proxy_cache_bypass $arg_nocache $arg_comment;
proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;Cache Key
Define the cache key that Nginx uses to store and retrieve cached objects.
proxy_cache_key $scheme$proxy_host$uri$is_args$args;Cacheable HTTP Methods
Specify which request methods can be cached.
proxy_cache_methods GET HEAD POST;Ignoring Certain Response Headers
Use proxy_ignore_headers to prevent caching when the upstream response contains headers such as Set-Cookie or specific Cache-Control directives (e.g., private, no-cache, no-store).
proxy_ignore_headers Set-Cookie Cache-Control;Cache Validity per HTTP Status
Configure how long responses with particular status codes are cached.
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;Cache Size and Buffering
Control memory buffers and temporary file handling for large responses.
proxy_buffering on;
proxy_buffers 8 8k;
proxy_buffer_size 8k;
proxy_busy_buffers_size 16k;
proxy_temp_path /tmp/proxy_temp;
proxy_max_temp_file_size 1024m;
proxy_temp_file_write_size 16k;Timeouts
Set connection, send, and read timeouts for upstream communication.
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;Locking and Stale Cache
Use proxy_cache_lock to ensure only one request updates a stale cache entry, with configurable lock timeout and age.
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
proxy_cache_lock_age 5s;Enable serving stale content when the upstream server returns errors or specific status codes:
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504 http_403 http_404;Revalidation
When a cached response expires, proxy_cache_revalidate on adds If-Modified-Since and If-None-Match headers to the upstream request, allowing the server to respond with 304 and refresh the cache.
proxy_cache_revalidate on;These configurations together enable fine‑grained control over Nginx caching, improving response times, reducing backend load, and providing resilience through stale‑while‑revalidate strategies.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
