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: 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_statusvariable to distinguish between cache hits and misses - Monitor
cache_miss_ratioto 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_timeoutto balance performance and backend load - Combine with
proxy_cache_validto 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.