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;
}
Caching:
Are you enabling the
proxy_cache
in yourlocation
orserver
block?For example, a few settings in the
location /
block from the Nginx docs.For the cache to work you need at least the two mandatory settings:
If you set it in some
location
block, are you sure that's the one you want to be caching?Analyzing
If you wish to analyze the hits, you can create a specific log for that:
And in the same
server
orlocation
block, you can add it as a secondary log, so you don't miss the other stuff:You can then check some stats:
HIT vs MISS vs BYPASS vs EXPIRED
awk '{print $3}' cache.log | sort | uniq -c | sort -r
MISS URLs:
awk '($3 ~ /MISS/)' cache.log | awk '{print $7}' | sort | uniq -c | sort -r
BYPASS URLs:
awk '($3 ~ /BYPASS/)' cache.log | awk '{print $7}' | sort | uniq -c | sort -r
MISS vs BYPASS
Analyzing source: - https://easyengine.io/tutorials/nginx/upstream-cache-status-in-access-log/
Another option for analyzing on the fly via console is to use GoAccess, a really nice real time web log analyzer, which only needs ncurses to work: https://goaccess.io/
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.
What are trying to cache? A cms? A static page? Usually if backed send no-cache , expire -1, or cache private, you will get misses . In case of cookie also you will hit misses.