What this cache checker tests
Most cache checkers request your URL once, from one server, and read one header. That tells you almost nothing: CDNs cache per edge location. Cloudflare alone runs 300+ data centers, and each keeps its own independent cache. This tool requests your URL from six locations on four continents simultaneously and reports, per location:
- Cache status — HIT, MISS, EXPIRED, DYNAMIC, BYPASS (or the CDN's equivalent)
- Edge location — which data center answered (the
cf-raycolo code; look up any code in our Cloudflare data center list) - TTFB — how long the response took from that location
- Age — how long the object has been sitting in cache
The CDN is detected automatically from response headers: cf-cache-status
and cf-ray for Cloudflare, x-served-by for Fastly,
x-amz-cf-pop for CloudFront, x-cache for Akamai,
cdn-cache for bunny.net and x-77-cache for CDN77.
Reading the results: every cf-cache-status value explained
The short version is below — for the full breakdown of every value, the difference between DYNAMIC and BYPASS, and the fix for each, read cf-cache-status explained.
| Status | What it means | Good or bad? |
|---|---|---|
HIT | Served straight from the edge cache — your origin was never contacted. | ✅ What you want |
MISS | Not in this location's cache. Fetched from origin, then stored for next time. | ⚠️ Slow for this visitor |
EXPIRED | Was cached, but the TTL ran out — revalidated at the origin. | ⚠️ Effectively a miss |
STALE | Served from cache while a fresh copy is fetched in the background. | ✅ Fast, slightly old |
REVALIDATED | Stale entry confirmed still fresh by the origin (304). | ✅ Cheap |
DYNAMIC | Cloudflare decided not to cache this — the default for all HTML. | ❌ Not cached at all |
BYPASS | The response opted out via no-store, private or a cookie. | ❌ Not cached at all |
NONE / UNKNOWN | No cache status header found — no CDN cache in front of this URL. | ❌ Nothing to hit |
CHALLENGE | Bot protection challenged our checker (data-center IP). Real browsers pass the challenge and see the normal cache status. | — inconclusive |
Common findings — and how to fix them
Every location shows DYNAMIC
Cloudflare doesn't cache HTML by default. Create a Cache Rule
("Eligible for cache" for your hostname or path), or send
Cloudflare-CDN-Cache-Control: max-age=… from your origin. Our
Cloudflare cache warming guide walks through it.
One location HITs, the rest MISS
That's per-location caching at work. The location with traffic stays warm; everywhere else, the first visitor pays the full origin round trip. The fix is either lots of global traffic — or cache warming: requesting your pages from every edge location on a schedule so the cache is already filled when a real visitor arrives.
Everything HITs but TTFB is still slow in some regions
Check the edge location column: if a request from Sydney is answered by a colo in Los Angeles, your CDN plan or DNS setup isn't routing visitors to their nearest data center. The cache is fine — the routing isn't.
HIT with a high Age
The object has been cached for a long time. That's good for speed — just make sure you purge on deploys so visitors don't see stale content, and re-warm right after (how to schedule warming around deploys).
Why we built this
This tool is the successor of cf-cache-status.net, a popular single-location Cloudflare cache checker. We rebuilt it with multi-location checks and support for all major CDNs, because the single biggest cache misconception is thinking of "the cache" as one thing. It's hundreds of independent caches — and this checker makes that visible in one click.
FAQ
What does cf-cache-status mean?
cf-cache-status is a response header Cloudflare adds to every request
passing through its network. It tells you whether the response came from Cloudflare's
edge cache (HIT), had to be fetched from your origin (MISS,
EXPIRED), or wasn't considered cacheable at all (DYNAMIC,
BYPASS).
Why does my page show DYNAMIC instead of HIT?
Cloudflare doesn't cache HTML by default — only static assets. DYNAMIC
means the response isn't cacheable under Cloudflare's default rules. Create a Cache Rule
marking your URLs "Eligible for cache", or send a
Cloudflare-CDN-Cache-Control header from your origin.
Why do different locations show different cache statuses?
CDNs cache per edge location — each of Cloudflare's 300+ data centers keeps its own cache. A page HIT in Frankfurt can be MISS in Singapore at the same moment. That's the whole reason this checker tests from multiple locations.
How do I turn a MISS into a HIT?
Make the response cacheable first (see DYNAMIC above). Then either wait for organic traffic to fill each location's cache — or warm it proactively. warmup.rocks requests your pages from 90+ edge locations on a schedule, so every location stays warm.
Is this checker free? Does it store my URLs?
Yes, it's free and requires no signup. Checks run live and results aren't stored — we keep a short-lived, in-memory rate-limit counter per IP and nothing else.
Stop checking. Start warming.
warmup.rocks requests your pages from 90+ CDN edge locations on a schedule and shows you the hit ratio per location, per run — for Cloudflare, Fastly, Akamai, CloudFront and more.
Start your 7-day free trial