SysAdmin Tools

A cache checker tells you whether a page is being served fresh from your origin server or from a cache layer sitting in front of it. Modern websites rarely talk straight to the origin on every request — a CDN like Cloudflare, a reverse proxy like Varnish or Nginx proxy_cache, or a WordPress plugin such as LiteSpeed Cache, WP Super Cache or W3 Total Cache can all quietly return a stored copy. That is great for speed, but it is exactly why a page can keep showing old content long after you have updated it.

This tool sends two real HTTP requests to your URL from our server, reads only the response headers, and reports which cache layers are involved and whether the copy you are being served may be stale. It looks at the headers that actually matter for caching — cf-cache-status, age, cache-control, expires, etag, last-modified, x-cache, x-proxy-cache, x-fastcgi-cache, x-varnish and x-litespeed-cache — and reports only what the headers show, naming the exact header as evidence rather than guessing.

Because it fires two requests about 1.5 seconds apart, it can also compare them: if the Age header keeps climbing or cf-cache-status flips from MISS to HIT, that is concrete proof a cache is serving the page. Use it when a deployment "did not take", when CSS goes missing after a cache clear, or when you simply want to confirm Cloudflare is caching what you think it is.

No login, no database, and we never log full URLs. The check runs entirely server-side — your browser never fetches the target — so it works on pages that would block a browser-based tool.

How to Use the Cache Checker

  1. 1

    Paste the URL to test

    Enter the full URL of the page you want to check, for example https://example.com/blog/my-post. If you omit the scheme we add https:// automatically. Test the exact URL users hit, including the path and any query string, since caches often key on the full URL.

  2. 2

    Click Analyze

    Our server sends two GET requests to the final URL about 1.5 seconds apart, following redirects if needed, and reads only the response headers — the page body is never downloaded. A fixed User-Agent is used and no cookies are sent.

  3. 3

    Read the cache signals

    The Cache Signals panel lists every caching header that was actually present — Cloudflare (cf-cache-status, cf-ray), Varnish (x-varnish), LiteSpeed (x-litespeed-cache) and generic ones like age, cache-control and x-cache — each shown with its real value as evidence.

  4. 4

    Check the comparison and verdict

    The comparison between request one and request two shows whether Age is increasing or cf-cache-status changed from MISS to HIT. The "What this means" panel translates the headers into plain language so you know whether to purge a cache and which layer to purge.

Understanding Cache Headers

Caching happens in layers, and each layer leaves its own fingerprint in the response headers. The job of a cache checker is to read those fingerprints without guessing. Cloudflare adds cf-ray to every proxied response and cf-cache-status when caching is in play — HIT means it served a cached copy, MISS means it fetched from origin and may now cache it, DYNAMIC means it is not caching the page at all, BYPASS means a rule told it to skip the cache, EXPIRED/REVALIDATED/STALE describe revalidation against the origin. Varnish advertises itself through x-varnish (transaction IDs) and often a Via header mentioning Varnish, while LiteSpeed uses x-litespeed-cache: hit or miss. The generic, server-agnostic signals are the HTTP standard ones: Cache-Control (the max-age / no-store policy the origin wants), Expires, ETag and Last-Modified (validators), and the widely used Age header, which reports how many seconds ago the shared cache stored the response. A large and growing Age is the clearest sign you are looking at a cached copy. WordPress caching plugins add their own headers such as x-wp-cf-super-cache, x-cache-enabled and x-wpo-cache, which this tool labels explicitly as plugin headers.
FieldDescription
cf-cache-statusCloudflare cache state: HIT (served from cache), MISS (fetched from origin), DYNAMIC (not cached), BYPASS (cache skipped by rule), EXPIRED/REVALIDATED/STALE (revalidation states).
ageSeconds since a shared cache stored this response. A value that grows between requests is strong evidence the page is being served from cache.
cache-controlThe caching policy requested by the origin — e.g. max-age=3600 (cacheable for an hour), no-store (never cache), private (browser only, not shared caches).
x-cache / x-proxy-cacheReverse-proxy cache status set by Nginx, Varnish or a CDN — typically HIT, MISS or BYPASS.
x-varnishVarnish transaction IDs. Two IDs usually mean the response was served from the Varnish cache.
etag / last-modifiedValidators used for conditional requests so caches can revalidate instead of re-downloading unchanged content.

Advertisement

Common Cache Checker Use Cases

A deployment did not take — the page still shows old content

You pushed an update but the live page is unchanged. Run the checker: a HIT with a large Age, or a plugin header like x-litespeed-cache: hit, tells you a specific cache layer is serving the old copy and exactly which one to purge — rather than clearing every cache blindly.

Confirming Cloudflare is actually caching

You set up a Cloudflare cache rule and want proof it works. A cf-cache-status of DYNAMIC means Cloudflare is not caching the HTML at all, while HIT on the second request confirms the rule is effective and the origin is being spared.

Diagnosing missing CSS or JS after a cache clear

When styles break after clearing a cache, stale or mismatched cached assets are usually the cause. Checking the cache headers on the CSS or JS URL shows whether an old copy is still being served and from which layer, so you can purge the right one.

Auditing a stacked cache (Cloudflare in front of Varnish)

Many setups run Cloudflare in front of Varnish or Nginx proxy_cache. Seeing cf-cache-status: DYNAMIC together with an x-varnish header reveals that Cloudflare is passing through but a cache behind it is serving the page — the kind of layered behaviour a single-request tool will miss.

Cache Checker — Frequently Asked Questions

What does cf-cache-status DYNAMIC mean?
DYNAMIC means Cloudflare is not caching this response and fetched it from your origin server. By default Cloudflare treats HTML as dynamic and only caches static assets (images, CSS, JS). To cache HTML you need a Cache Rule or Page Rule with "Cache Everything". If you still see DYNAMIC after adding one, check that your origin is not sending Cache-Control: no-store/private or Set-Cookie on the response, as those can prevent Cloudflare from caching.
What is the Age header in HTTP?
The Age header is the number of seconds since a shared cache (CDN or reverse proxy) stored the response it is now serving you. Age: 0 usually means the cache just fetched a fresh copy; a large Age means you are being served an older cached copy. If Age keeps increasing each time you request the page, that is clear proof the page is being served from cache rather than regenerated on every request.
How do I know if Varnish is serving my page?
Look for the x-varnish header — Varnish adds it to responses it handles, and when it serves a cached object the header usually contains two transaction IDs instead of one. A Via header mentioning "varnish" and an Age header that climbs over time are further signs. This tool flags the x-varnish and Via headers explicitly when they are present so you do not have to read the raw headers yourself.
Why does my page show old CSS after clearing cache?
Usually one cache layer was not cleared, or the browser or CDN is still holding an old copy of the CSS file under its old URL. CSS and JS are often cached aggressively with long max-age values. Check the cache headers on the CSS file URL itself: if you see a HIT or a large Age, that layer is still serving the old file. Fixes include purging that specific layer, adding a version query string or hashed filename so the URL changes, or lowering the asset Cache-Control max-age.
What does cf-cache-status HIT vs MISS mean?
HIT means Cloudflare served the response from its edge cache without contacting your origin — fast, and a sign caching is working. MISS means Cloudflare did not have it cached and fetched it from your origin; if the content is cacheable it may store it so the next request is a HIT. Seeing MISS on the first request and HIT on a second request to the same URL is the normal, healthy pattern for a page that Cloudflare is allowed to cache.
What is the x-cache header and what values does it have?
x-cache is a non-standard header set by many reverse proxies and CDNs (Nginx, Varnish, CloudFront and others) to report whether the response came from their cache. The common values are HIT (served from cache), MISS (fetched from origin) and BYPASS (cache deliberately skipped). Some proxies also expose x-proxy-cache, x-cache-status or x-fastcgi-cache with the same style of values. The exact wording depends on the software and its configuration.
How do I force Cloudflare to recache my page?
Purge the cached copy so the next request becomes a MISS and repopulates the cache. In the Cloudflare dashboard use Caching → Configuration → Purge Cache, either "Purge Everything" or purge the specific URL. You can also purge by URL through the Cloudflare API. After purging, request the page twice: the first should show cf-cache-status: MISS and the second HIT, confirming the fresh copy is now cached.
What does cache-control: no-store mean?
Cache-Control: no-store tells every cache — browser, CDN and reverse proxy — not to store any copy of the response at all; each request must go to the origin. It is used for sensitive or highly dynamic pages such as account or checkout pages. If a page you want cached is returning no-store, that is why no cache layer is keeping it, and you will typically see cf-cache-status: DYNAMIC or BYPASS alongside it.
How do I check if LiteSpeed Cache is working?
LiteSpeed sets the x-litespeed-cache header, usually with the value "hit" when it served a cached page and "miss" when it did not. Request the page, then request it again: the first may be a miss and the second a hit once the page is cached. If you never see the header at all, LiteSpeed Cache may be disabled, the page may be excluded by a rule, or a cookie or query string may be preventing caching for that request.
Why is cf-cache-status BYPASS on my WordPress site?
BYPASS means a rule explicitly told Cloudflare not to serve this request from cache. On WordPress this is common and often intentional: logged-in users, the wp-admin area, and pages that set cookies (comments, WooCommerce carts) are usually bypassed so visitors never see each other’s personalised content. If you see BYPASS on a public page that should be cached, check your Cache Rules for cookie or URL conditions, and make sure the response is not setting a Set-Cookie header that triggers the bypass.

Related Tools