Skip to main content

Implementing Microcaching

1. Setting Short Cache Times

Directive Values Description
proxy_cache_valid 1m, 5m, 10m Sets the cache validity time for different response types
fastcgi_cache_valid 1m, 5m, 10m Sets the cache validity time for FastCGI responses
uwsgi_cache_valid 1m, 5m, 10m Sets the cache validity time for uWSGI responses

Example: Setting cache validity to 1 minute

location /api/ {
    proxy_cache my_cache;
    proxy_cache_valid 1m;
}

Example: Setting cache validity for different response types

location /api/ {
    proxy_cache my_cache;
    proxy_cache_valid 200 1m;
    proxy_cache_valid 404 10m;
    proxy_cache_valid 500-599 1h;
}

2. Caching Dynamic Content

Directive Description Values Notes
proxy_cache Enables or disables caching of responses from a proxied server off, on, or a cache zone name Must be set in http, server, or location
proxy_cache_valid Sets caching time for different response codes Time duration (e.g., 1h, 30m) Can be set per response code: 200 1h, 404 1m
proxy_cache_key Defines the cache key for a request String with variables Default: $scheme$proxy_host$request_uri
proxy_cache_min_uses Minimum number of requests before caching begins Integer (default: 1) Useful for avoiding caching of infrequent requests
proxy_cache_use_stale Defines when stale content can be served error, timeout, invalid_header, updating, http_500, etc. Can be combined: error updating
proxy_cache_lock Prevents multiple simultaneous cache misses for the same key on, off Improves performance for high-load scenarios

Example: Basic Dynamic Content Caching

location /api/ {
    proxy_pass http://backend;
    proxy_cache my_cache;
    proxy_cache_valid 200 1h;
    proxy_cache_key $uri;
    proxy_cache_min_uses 2;
}

Example: Caching with Stale Content Fallback

location /api/ {
    proxy_pass http://backend;
    proxy_cache my_cache;
    proxy_cache_use_stale error timeout updating 500 502 503;
    proxy_cache_valid 200 1h;
    proxy_cache_valid 404 1m;
}
Note: When using proxy_cache_lock, it's recommended to set a reasonable proxy_cache_valid time to avoid long lock waits.
Warning: Caching dynamic content can lead to stale data if not configured carefully. Ensure cache invalidation is handled properly.

3. Using Cache Bypass for Logged-in Users

Directive Description Example
proxy_cache_bypass Skips cache lookup if the request matches the condition proxy_cache_bypass $cookie_user;
set Sets a variable to a value or result of a condition set $skip_cache 0;

Example: Bypass cache for logged-in users

location / {
    proxy_cache my_cache;
    proxy_cache_bypass $cookie_user;
    proxy_no_cache $cookie_user;
}

Example: Using a variable to control cache bypass

location / {
    proxy_cache my_cache;
    set $skip_cache 0;
    if ($cookie_user) {
        set $skip_cache 1;
    }
    proxy_cache_bypass $skip_cache;
}

4. Configuring Stale Cache

Directive Values Description
proxy_cache_use_stale error, timeout, invalid_header, updating, http_500, http_502, http_503, http_504, http_403, http_404, off Specifies when to serve stale cached content instead of retrying the request.
proxy_cache_valid 200 1h, 404 1m, any 5m Defines how long to cache responses based on status code.
proxy_cache_lock on, off Prevents multiple requests from hitting the backend simultaneously for the same cache key.
proxy_cache_lock_timeout 5s, 10m Timeout for the cache lock before allowing a new backend request.

Example: Stale Cache Configuration

proxy_cache_use_stale error timeout updating http_500 http_502;
proxy_cache_valid 200 1h;
proxy_cache_valid 404 1m;
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
Note: The updating flag allows serving stale content while a new version is being fetched, reducing latency for subsequent requests.

5. Setting Cache Lock Timeout

Directive Values Description
proxy_cache_lock on | off Enables or disables cache locking to prevent multiple requests from hitting the backend simultaneously for the same cache key.
proxy_cache_lock_timeout time Defines the maximum time (in seconds) to wait for a cache lock before proceeding with the backend request. Default is 5s.
proxy_cache_lock_age time Defines the time (in seconds) after which a cache lock is released even if the backend response has not been received. Default is 5s.

Example: Configuring Cache Lock Timeout

location /api/ {
    proxy_cache my_cache;
    proxy_cache_lock on;
    proxy_cache_lock_timeout 10s;
    proxy_cache_lock_age 5s;
    proxy_pass http://backend;
}

6. Implementing Cache Warming

Cache warming is the process of pre-populating cache entries with frequently accessed content to reduce latency and improve response times during high traffic periods.

Directive Description Example
proxy_cache_warmup Enables cache warming for proxy caches proxy_cache_warmup on;
proxy_cache_warmup_attempts Number of attempts to warm the cache proxy_cache_warmup_attempts 3;
proxy_cache_warmup_timeout Timeout for cache warming operations proxy_cache_warmup_timeout 30s;

Example: Basic Cache Warming Configuration

location /api/ {
    proxy_cache my_cache;
    proxy_cache_warmup on;
    proxy_cache_warmup_attempts 2;
    proxy_cache_warmup_timeout 60s;
    proxy_pass http://backend;
}
Note: Cache warming is particularly useful for APIs or content that experiences sudden traffic spikes.
Warning: Ensure that the backend server can handle multiple simultaneous requests during cache warming to avoid overloading.

7. Using Edge Side Includes

Edge Side Includes (ESI) is a specification for content composition in web applications, allowing parts of a page to be dynamically included or excluded based on conditions. Nginx supports ESI through the ngx_http_esi_module.

Directive Description Default
esi Enables or disables ESI processing for a location. off
esi_ignore_errors Controls whether to ignore errors during ESI processing. off

Example: Basic ESI Configuration

location / {
    esi on;
    proxy_pass http://backend;
}

Example: ESI with Substitution

location / {
    esi on;
    proxy_pass http://backend;

    # ESI includes a dynamic fragment
    proxy_set_header X-ESI-Include "fragment.html";
}
Note: ESI processing is handled by the ngx_http_esi_module. Ensure that the backend server supports ESI tags in its response.

ESI Use Cases

  • Dynamic content inclusion in static pages.
  • Personalized content rendering (e.g., user-specific widgets).
  • Reducing server load by caching static parts of pages.

8. Configuring Slice Module

Directive Values Description
slice on | off Enables or disables the slice module. Default is off.
slice_buffer_size size Sets the buffer size for slice module. Default is 1m.
slice_max_size size Maximum size of a slice. Default is 10m.
slice_min_size size Minimum size of a slice. Default is 1k.

Example: Basic Slice Module Configuration

location / {
    slice on;
    slice_buffer_size 2m;
    slice_max_size 5m;
    slice_min_size 2k;
}
Note: The slice module is used to split large responses into smaller chunks for efficient caching.

9. Setting Cache Vary Headers

Directive Values Description
proxy_cache_vary on | off Enables or disables adding Vary headers to cached responses. Default is off.
proxy_cache_vary $http_accept_encoding Example of setting Vary header based on Accept-Encoding to handle content encoding variations.

Example: Setting Vary Header for Content Encoding

location / {
    proxy_pass http://backend;
    proxy_cache my_cache;
    proxy_cache_vary $http_accept_encoding;
}
Note: The Vary header tells the client or proxy which request headers were used to select the cached response. This is critical for ensuring that different content versions (e.g., compressed vs uncompressed) are correctly served.

10. Monitoring Cache Hit Ratio

Metric Description Formula Recommended Threshold
cache_hit_ratio Percentage of requests served from cache (cache_hits / (cache_hits + cache_misses)) * 100 ≥ 80%
cache_miss_ratio Percentage of requests that missed the cache (cache_misses / (cache_hits + cache_misses)) * 100 ≤ 20%

Example: Nginx Cache Metrics Configuration

http {
    # Enable cache metrics logging
    map $upstream_cache_status $cache_status {
        default "miss";
        hit "hit";
    }

    log_format cache_log "$time_local - $request_method $request_uri - Cache Status: $cache_status";

    server {
        listen 80;
        location / {
            proxy_cache my_cache;
            proxy_cache_valid 200 1h;
            proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
            proxy_cache_lock on;

            # Log cache hits/misses
            access_log /var/log/nginx/cache_access.log cache_log;
        }
    }
}
Note: Use tools like prometheus and grafana to monitor cache hit ratio over time.

Cache Hit Ratio Monitoring Best Practices

  • Set up automated alerts when cache hit ratio drops below 80%
  • Log cache status for each request to analyze performance trends
  • Use proxy_cache_status variable to distinguish between cache hits and misses
  • Monitor cache_miss_ratio to identify content that may benefit from longer cache durations

11. Implementing Cache Stampede Prevention

Example: Basic Cache Stampede Prevention with Nginx

location /api/data {
    proxy_cache my_cache;
    proxy_cache_valid 200 1h;
    proxy_cache_lock on;
    proxy_cache_lock_timeout 5s;

    proxy_pass http://backend;
}
Directive Description Default Notes
proxy_cache_lock Enables cache locking to prevent multiple requests from hitting the backend simultaneously off Set to on to enable stampede prevention
proxy_cache_lock_timeout Timeout for cache lock before allowing backend request 5s Adjust based on backend response time
proxy_cache_lock_age Time to wait before revalidating cached entries 5m Prevents stale data from being served too long
Note: proxy_cache_lock ensures that only one request triggers a cache miss, while others wait for the result.
Warning: Setting proxy_cache_lock_timeout too low can cause excessive backend load if the cache is frequently invalidated.

Key Points for Cache Stampede Prevention

  • Use proxy_cache_lock on; to prevent concurrent backend hits
  • Set proxy_cache_lock_timeout to balance performance and backend load
  • Combine with proxy_cache_valid to define cache TTLs
  • Monitor backend response times to tune lock duration

12. Configuring Cache Min Uses

Directive Values Description
proxy_cache_min_uses 1 Minimum number of requests for a cache entry to be created
fastcgi_cache_min_uses 1 Minimum number of requests for a FastCGI cache entry to be created
scgi_cache_min_uses 1 Minimum number of requests for an SCGI cache entry to be created
uwsgi_cache_min_uses 1 Minimum number of requests for a uWSGI cache entry to be created

Example: Setting proxy_cache_min_uses

location /api/ {
    proxy_cache my_cache;
    proxy_cache_min_uses 3;
    proxy_pass http://backend;
}
Note: Setting proxy_cache_min_uses to a higher value can help reduce cache pollution by ensuring that only frequently accessed content is cached.

Was this article helpful?