How the Cloudflare cache checker works
- We validate the URL. Only public http and https sites on ports Cloudflare proxies are accepted. Private and internal addresses are refused.
- We request it like a browser. The request comes from our server, follows up to five redirects and is read for headers only.
- We read the response headers.
cf-cache-status,cache-control,age,cf-rayand about twenty others are decoded. - We explain the result. You get a verdict, a checklist with a score and the changes that would move the status towards HIT.
The warm-up test sends two or three requests in a row. A cacheable file shows MISS first and HIT afterwards, which proves your caching rules work and not just that a copy happened to exist.
Cloudflare cache status reference
Cloudflare adds a cf-cache-status header to responses that pass through its cache. These are the values you can see and what to do about each one.
| Status | What it means | What to do |
|---|---|---|
HIT | The file was served from Cloudflare's cache. | Nothing to fix. Check the cache lifetime if you want fewer refreshes. |
MISS | Not in cache in this data center, so the origin was asked. | Normal on a first request. Repeat the check; if it stays MISS, look at Cache-Control and cookies. |
EXPIRED | A cached copy existed but its lifetime had ended. | Raise the TTL or add stale-while-revalidate. |
REVALIDATED | An expired copy was confirmed as current by the origin and served from cache. | Healthy. ETag or Last-Modified headers are working. |
STALE | An expired copy was served, for example because the origin was slow or down. | Check origin health and your stale-if-error settings. |
UPDATING | An old copy was served while a new one loads in the background. | Normal with stale-while-revalidate. |
BYPASS | Cloudflare was told not to cache the response. | Remove private, no-store or no-cache for public content, or review Cache Rules. |
DYNAMIC | The content is not eligible for caching by default. | Create a Cache Rule marked Eligible for cache, or send a public Cache-Control header. |
NONE / UNKNOWN | The response was generated without a cache lookup. | Look at redirect rules, WAF actions and Workers on this URL. |
Why you see DYNAMIC (and how to cache HTML)
Cloudflare decides what to cache by file extension, not by content type. Common static types such as .css, .js, .png, .jpg, .webp, .svg, .woff2, .pdf and .zip are cached by default. HTML and JSON are not, so they report DYNAMIC.
To cache a page, open Caching, then Cache Rules, match the hostname and path, choose Eligible for cache and set an Edge TTL. Keep logged-in areas out of the rule: bypass the cache when a session cookie is present, and never cache cart, checkout or account pages.
Headers that control Cloudflare caching
Cache-Control- The main switch.
public,max-ageands-maxageallow caching.private,no-storeandno-cachestop Cloudflare from caching the response. s-maxage- Cache lifetime for shared caches such as Cloudflare. It overrides
max-agethere, so browsers and the edge can use different lifetimes. Set-Cookie- A response that sets a cookie is usually not cached. Remove cookies from public pages and static files.
Age- How many seconds the cached copy has been stored. It appears on cached responses and tells you how much of the lifetime is left.
ETagandLast-Modified- Let Cloudflare ask your origin whether an expired copy is still valid, which is faster than downloading it again.
cf-ray- A unique request ID that ends with the three-letter code of the data center that answered, for example
LHRfor London.
Safe starting points:
# Versioned static files (app.3f9c1.js)
Cache-Control: public, max-age=31536000, immutable
# Pages you want cached at the edge
Cache-Control: public, max-age=0, s-maxage=3600, stale-while-revalidate=86400
How to improve your Cloudflare cache hit ratio
- Give every static file a versioned name and a one-year lifetime.
- Create Cache Rules for pages that are identical for all visitors.
- Remove
Set-Cookiefrom public responses. - Keep query strings stable. Random parameters create a new cache entry each time.
- Add
stale-while-revalidateso expired copies are refreshed in the background. - Turn on Tiered Cache to cut origin requests from first visitors in each region.
- Purge single URLs after a change instead of purging everything.
What this tool can't tell you
- One location. The result comes from the Cloudflare data center closest to our server. The colo code in the result shows which one. Other regions have their own cache.
- Anonymous requests only. The checker sends no cookies or logins, so it cannot see what a logged-in visitor gets.
- No dashboard settings. Cache Rules, Page Rules and Workers are visible only through their effect on the response headers.
- Not affiliated with Cloudflare, Inc. Cloudflare is a trademark of its owner.
Frequently asked questions
What does cf-cache-status HIT mean?
HIT means Cloudflare found a copy of the file in its cache and answered without contacting your origin server. It is the result you want for static files and cacheable pages.
Why does my site show DYNAMIC?
Cloudflare only caches static file types such as images, CSS and JavaScript by default. HTML pages and API responses are marked DYNAMIC unless a Cache Rule or your cache headers make them eligible for caching.
Why is the first request a MISS and the second a HIT?
The first request fills the cache, so Cloudflare has to ask your origin for the file. The next request in the same data center is then answered from cache. Use the warm-up test to see this sequence.
What is the difference between BYPASS and DYNAMIC?
BYPASS means Cloudflare was told not to cache the response, for example by Cache-Control: private or no-store, or by a rule. DYNAMIC means the content type is not cached by default and nothing asked for it to be cached.
Does Cloudflare cache HTML?
Not by default. To cache HTML you create a Cache Rule marked Eligible for cache, or use Automatic Platform Optimization for WordPress. Avoid caching pages that differ per visitor, such as account, cart and checkout pages.
Is a HIT here a HIT for visitors everywhere?
Not necessarily. Each Cloudflare data center keeps its own cache unless Tiered Cache is on. This tool shows the data center closest to its own server (the colo in the result), so a visitor in another region may see a MISS first.
How do I clear the Cloudflare cache for one URL?
Open Caching, then Configuration, then Purge Cache in the Cloudflare dashboard and choose Custom Purge. Enter the URL you want to remove, then run this checker again and expect a MISS followed by a HIT.
Why does the tool say my site is not served through Cloudflare?
None of the Cloudflare response headers were present. Check that the DNS record is proxied (orange cloud), that you entered the right hostname, and that the site is not behind another CDN.
Is this Cloudflare cache checker free and safe to use?
Yes, it is free and needs no account. It only contacts public websites on ports Cloudflare proxies, never private addresses, and it limits how often each visitor and each website can be checked.