My proxy cache path is set to a very high size
proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=staticfilecache:180m max_size=700m;
and the size used is only
sudo du -sh *
14M cache
4.0K proxy
Proxy cache valid is set to
proxy_cache_valid 200 120d;
I track HIT and MISS via
add_header X-Cache-Status $upstream_cache_status;
Despite these settings I am seeing a lot of MISSes. And this is for pages I intentionally ran a cache warmer an hour ago.
How do I debug why these MISSes are happening? How do I find out if the miss was due to eviction, expiration, some rogue header etc? Does Nginx provide commands for this?
Edit: Full config
# at http level
proxy_cache_path /var/lib/nginx/cache levels=1:2 inactive=400d keys_zone=staticfilecache:180m max_size=700m;
proxy_temp_path /var/lib/nginx/proxy;
proxy_connect_timeout 30;
proxy_read_timeout 120;
proxy_send_timeout 120;
#prevent header too large errors
proxy_buffers 256 16k;
proxy_buffer_size 32k;
#httpoxy exploit protection
proxy_set_header Proxy "";
# at server level
add_header Cache-BYPASS-Reason $skip_reason;
# define nginx variables
set $do_not_cache 0;
set $skip_reason "";
set $bypass 0;
# security for bypass so localhost can empty cache
if ($remote_addr ~ "^(127.0.0.1|Web.Server.IP)$") {
set $bypass $http_8X0;
}
# skip caching WordPress cookies
if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) {
set $do_not_cache 1;
set $skip_reason Cookie;
}
# Don't cache URIs containing the following segments
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php") {
set $skip_cache 1;
set $skip_reason URI;
}
# https://guides.wp-bullet.com/how-to-configure-nginx-reverse-proxy-wordpress-cache-apache/
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Host $host;
proxy_set_header Accept-Encoding "";
# may need to comment out proxy_redirect if get login redirect loop
proxy_redirect off;
proxy_cache_key "$scheme://$host$uri";
add_header X-Nginx-Cache-Head "$scheme://$host$uri";
proxy_cache staticfilecache;
proxy_cache_valid 200 301 302 100d;
proxy_cache_valid 404 1m;
add_header Cache-Control public;
proxy_ignore_headers Expires;
proxy_ignore_headers "Cache-Control";
proxy_ignore_headers X-Accel-Expires;
proxy_hide_header "Cache-Control";
proxy_hide_header Pragma;
proxy_hide_header Server;
proxy_hide_header Request-Context;
proxy_hide_header X-Powered-By;
proxy_cache_revalidate on;
proxy_hide_header X-AspNet-Version;
proxy_hide_header X-AspNetMvc-Version;
#proxy_pass_header X-Accel-Expires;
add_header X-Nginx-Cache-Status $upstream_cache_status;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_cache_bypass $arg_nocache $do_not_cache $http_8X0;
proxy_no_cache $do_not_cache;
}
location ~* \.(jpg|png|gif|jpeg|css|js|mp3|wav|swf|mov|doc|pdf|xls|ppt|docx|pptx|xlsx)$ {
proxy_cache_valid 200 120d;
expires 364d;
add_header Cache-Control public;
proxy_pass http://127.0.0.1:8000;
proxy_cache staticfilecache;
add_header X-Nginx-Cache-Status $upstream_cache_status;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
}
Best Answer
You may need to set the
inactive
parameter onproxy_cache_path
to something greater than120d
(or whatever you want your max cache time to actually be). The default setting for inactive is 10 minutes. So long as the URL you're caching is accessed within the inactive parameter's time frame your cache is valid but if it's not accessed within that time frame it will fall out of cache. See Understanding the nginx proxy_cache_path directive for more information.I believe this falls outside the typical $upstream_cache_status style debugging because cache cleanup doesn't happen within the request/response cycle. AFAIK an nginx worker process does cache clean up as a low priority task if it's not doing anything else. I'm not sure where this activity would show up in logs but it's likely only going to show up with a debug enabled build.