Cache hit / cache miss

A hit means the nearby cache already had the answer. A miss means it had to go ask your real server, and the visitor feels the wait.

did it come from the cachewhy is it still hitting my servercach misscache hit ratiox-cache HIT headerwas this response cached or notthe CDN keeps going back to my serverhow do I tell if caching is working

See it

Live demo coming soon

What it is

Most requests through a cache end as a hit (the edge already had a valid copy and answered in a few milliseconds) or a miss (it had nothing usable, so it went to the origin and waited). The status header tells a longer story than those two words, though. Providers report it in x-cache, cf-cache-status, or x-vercel-cache with values like HIT, MISS, STALE, EXPIRED, REVALIDATED, and BYPASS. STALE means you were handed an expired copy on purpose while a refresh ran behind you; BYPASS, or a plain pass-through, means the cache looked at the request and declined to take part at all. And a miss only turns into a stored copy when the response policy allows storing it, so an uncacheable route can miss forever without ever filling.

Misses are not failures by themselves. Somebody has to be first in every city, and each PoP fills its own cache independently, so a MISS in Sydney and a HIT in Dublin at the same moment is normal. What matters is the hit ratio over time: above 90 percent for static assets is healthy, and a low number on content that should be cacheable means something is wrong with your headers or your cache key.

The usual culprits behind permanent misses: a 'Set-Cookie' on the response (many CDNs refuse to store one by default), a marketing query string like ?utm_source splitting one page into thousands of cache entries, a too-broad Vary header, or a TTL so short that entries expire before the second visitor shows up. Check the cache key before you blame the CDN.

Ask AI for it

Instrument and improve the CDN cache hit ratio for this site. Log the provider's cache status header (cf-cache-status / x-cache / x-vercel-cache) per route, then fix the misses: strip tracking query parameters like utm_source from the cache key, stop sending Set-Cookie on cacheable responses, narrow the Vary header to Accept-Encoding, and raise s-maxage with stale-while-revalidate on pages that change rarely. Report the before and after hit ratio per route.

You might have meant

cache keycdnorigin serveredge cache hit ratiovary header