Understanding cache HITs & MISSes
How to read the X-XSpeed-Cache header and tell exactly which layer served a page.
Every request to your site is either a HIT (served from cache) or a MISS (rendered fresh by WordPress). Knowing which is which — and which layer served the hit — is the fastest way to confirm caching is working.
The X-XSpeed-Cache header
xSpeed Cache adds a response header to every front-end request so you can see the cache status at a glance:
x-xspeed-cache: HIT (nginx)
The value tells you exactly how the page was served:
| Value | Meaning | Typical speed |
|---|---|---|
HIT (nginx) | Served as a static file directly by the web server, before PHP runs | ~5–15ms |
HIT (php) | Served from cache by the PHP drop-in (the fallback path) | ~50–90ms |
MISS | Not cached — WordPress rendered the page and stored it for next time | full page load |
HIT (nginx) is the fast path you want. It means the static-rewrite rule is engaged and the request never touched PHP. HIT (php) still serves cached HTML, but through PHP — usually a sign the server-level rewrite isn’t active yet (check the Cache panel for the rewrite banner).
How to check it
Browser DevTools — open the Network tab, reload the page, click the document request, and look under Response Headers for x-xspeed-cache.
Command line:
curl -sI https://your-site.com/ | grep -i x-xspeed-cache
The first visit to a fresh URL is expected to be a MISS. Reload once and it should flip to a HIT.
Why some pages always MISS
A MISS on every load usually isn’t a bug — some pages are meant to bypass cache:
- Logged-in users are served uncached pages.
- Excluded paths like
/cart,/checkout, and/my-accountare never cached (by default and via your exclusions). - Cookies or query parameters on your exclusion list force a bypass.
- Nonced or personalized content shouldn’t be cached.
The hit ratio
Your dashboard shows a hit ratio (HITs ÷ total requests over the last 24 hours). A healthy public site trends high (80%+). A persistently low ratio points at an overly-broad exclusion, a caching conflict, or a rewrite that isn’t engaged — start by confirming a plain post returns HIT (nginx).