Back to blog

How to Check CDN Cache Hits: Understanding HIT, MISS, and Age

CdnChart Technical TeamPublished on 2026-09-1415 min read
How to Check CDN Cache Hits: Understanding HIT, MISS, and Age

The CDN is already enabled, and static files are loading normally, but when you open the response headers:

CF-Cache-Status: MISS
Age: 0

Refresh once, and it changes to:

CF-Cache-Status: HIT
Age: 18

Many people start to wonder at this point: the first timeMISS— does that mean the CDN isn't working?Age: 18Does it mean there are 18 seconds left in cache, or that the file has existed for 18 seconds? If there is never anyAge, are all requests going back to origin?

In fact, you can't judge CDN caching from a single field or a single request. You need to look atcache status, Age, cache-control headers, request URL, and test nodetogether.

Here's the short answer first:

Field or status

What it usually means

What you can't conclude directly

HIT

The current cache layer found a reusable response and served it directly for this request

Does not mean all regions and all URLs are hits

MISS

The current cache layer did not find an object it can use directly and needs to fetch content from upstream

Does not necessarily mean no layer has a cache, nor does it mean the CDN isn't working

Age: 18

The response is estimated to be 18 seconds old since it was generated by the origin or last successfully validated

Not response time, and not necessarily the remaining TTL

Let's break down these three concepts clearly.

First confirm: which CDN's cache header are you seeing?

HITandMISSare common names, but there is no single response header name for CDN cache status that all vendors use identically.

You might see:

CF-Cache-Status: HIT

You might also see:

X-Cache: Hit from cloudfront

It could also be a vendor-specificX-Cache-Status,X-CDN-Cache, or the result may only be available in the console and access logs. The same word can also have slightly different meanings across vendors, multi-layer caches, and reverse proxies.

So the first step is not memorizing fields, but determining:

  1. Which CDN the current domain uses;

  2. Which response header is provided by that CDN;

  3. Whether there is another CDN, load balancer, or reverse proxy in front of the website.

If you're not sure about the vendor, you can first useCdnChart CDN Checkto look at clues such as CNAME, response IP, ASN, and HTTP response headers, then refer to the vendor's official documentation to interpret cache status. For the identification logic, you can also readHow to identify which CDN a website uses.

What does HIT mean?

HITThe core meaning is:The cache layer currently handling the response already has a cache object that meets the conditions of this request and can still be used.

The request process is roughly:

用户请求 → CDN节点查找缓存 → 找到可用对象 → 直接返回

Compared with fetching the complete file from origin, a cache hit usually reduces origin requests and cross-region transfer.

However, seeing a singleHITonly proves that this one request, this URL, and this node had a cache hit.

It cannot prove:

  • That nodes in other cities or carriers have also cached it;

  • That all images, scripts, and APIs referenced by the homepage are hits;

  • That different query parameters, cookies, or request headers use the same cache;

  • That the overall website cache hit rate is high;

  • That the current configuration is necessarily safe and reasonable.

For example, the following two URLs are two different cache keys in many configurations:

https://example.com/app.js?v=100
https://example.com/app.js?v=101

Even if the first URL is alreadyHIT, the second URL may still be aMISSon its first visit. If the system appends a random parameter to every request, the cache will be difficult to reuse.

What does MISS mean? Does it always mean a request went back to origin?

MISSusually means:The current cache layer did not find an object that can be used directly for this request.

The most common process is:

用户请求 → 边缘节点未命中 → 从源站获取 → 返回并按规则缓存

So when a new file is accessed by a node for the first time, aMISSis normal. As long as the response allows caching, the second request for the same URL may become aHIT.

But in modern CDN architectures, you can't treat everyMISSas simply meaning “this request definitely went straight to origin.”

The reason is that a CDN may have two or even multiple cache tiers:

用户 → 边缘节点 → 上层缓存 / Origin Shield → 源站

The edge node does not have the object locally, so it can record a localMISS; but an upper-tier cache may already have the content, so the request is satisfied by the upper-tier cache and the origin does not transfer the complete file again.

Whether a vendor exposes the local tier, final tier, or aggregate status depends on its documentation and logs.

In addition, when multiple users request a large file that is not yet cached at almost the same time, some CDNs collapse those origin requests: the first request fills the cache, and the rest wait and reuse the result. AWS, inCloudFront custom origin request behavior, calls this mechanism request collapsing, which prevents every concurrent request from individually accessing the origin.

Therefore, the most reliable evidence for whether requests truly reach the origin usually comes from:

  • Origin request counts and origin traffic in the CDN console;

  • Detailed cache status in CDN access logs;

  • Origin access logs;

  • Origin Shield or upper-tier cache metrics.

A singleMISSseen by one client is only a clue, not a complete account of the entire cache chain.

What does Age mean?

Ageis a standard HTTP response header measured in seconds.

According toRFC 9111 HTTP Caching, it represents the cache's estimate of how many seconds have passed since the response was generated by the origin or last successfully validated. This value also includes the time the response has spent in the cache chain and in transit.

For example:

Cache-Control: public, max-age=3600
Age: 600

It can be roughly understood as: this response has been around for about 600 seconds since it was generated or validated.

If no other cache policy overrides it, andmax-age=3600is indeed the TTL used by the shared cache, then in theory about 3000 seconds of freshness remain:

3600 - 600 = 3000秒

But this can only serve as an approximate judgment.

The CDN may have an independent edge TTL configured, may prioritize readings-maxageorCDN-Cache-Control, and may also have tiered caching, revalidation, and vendor-specific rules. Therefore, you cannot rely onAgealone to infer the final expiration time.

What Age is not

Ageis easily misread. It is not:

  • The time this request took;

  • The age of the file since it was created;

  • The DNS cache TTL;

  • How many seconds remain in the cache;

  • How long the CDN node has been running;

  • The version number of a static asset.

Age: 120does not mean the page took 120 seconds to load, nor that only 120 seconds remain in cache.

Why does Age keep increasing?

When the same URL is repeatedly accessed on the same cache node, if the same cache object is reused each time,Ageoften increases over time:

# 第一次
CF-Cache-Status: HIT
Age: 21

# 几秒后
CF-Cache-Status: HIT
Age: 27

This is a fairly typical sign of normal cache hits.

Why does Age suddenly decrease or reset to zero?

Common reasons include:

  • The request was routed to another edge node;

  • The cache was actively purged;

  • The object expired and was fetched from origin again;

  • The cache object was evicted and refilled;

  • The CDN revalidated with the origin and reset the age;

  • Multi-tier caching returned age information from different tiers.

Cloudflare, inCache Response Status documentation, states that itsAgeresets after revalidation, purging, or eviction; when tiered caching is used, it may also inherit the upper-tier cache'sAge.

If Age is missing, does that mean there was no hit?

No.

RFC 9111 also notes: if there is noAge, you cannot conclude that the request definitely contacted the origin. Some caches or proxies may not expose this field, and some response statuses may not include it.

Conversely, having anAgeshould not be judged in isolation from other fields. Some upstream proxies or origins send their ownAge, and the CDN may pass it along.

It is best to check cache status,Via, vendor-specific headers, and cache-control policies together.

Besides HIT and MISS, what other statuses might you see?

Vendor names are not exactly the same. Below are common meanings and typical examples; when interpreting a specific website, use the corresponding vendor's official definitions.

Status

Common meaning

Troubleshooting focus

HIT

Found a usable cache and returned it

Then check whether Age is reasonable and consistent across regions

MISS

The current cache layer has no directly usable object

First visit, cache key, TTL, whether it was successfully written to cache

BYPASS

The object may have entered the cache flow but bypassed caching due to response headers or rules

private,no-store,Set-Cookie, authorized requests

DYNAMIC

The request was judged not cacheable before cache lookup

URL rules, file types, cache mode, dynamic pages

EXPIRED

An existing object expired and a new response is needed from upstream

Whether TTL is too short and whether the origin is healthy

REVALIDATED/RefreshHit

Upstream confirmed the content has not changed, so the cache continues to be used

ETag,Last-Modified, conditional requests

STALE

The cache expired, but the stale copy is still returned under specific conditions

Origin failure, stale policy, consistency requirements

UPDATING

Return the old cache first while updating in the background

Whether background refresh is enabled

NONE/UNKNOWN

The response was generated before the normal cache flow, or no recognizable status was obtained

WAF, edge functions, redirects, and error pages

There are two easily confused points here.

First,BYPASSandDYNAMICcan both appear as requests going upstream, but for different reasons: the former usually means response headers or rules prevent the object from being cached, while the latter may be identified as dynamic content at the request stage.

Second,REVALIDATEDdoes not mean re-downloading the entire file.

The CDN can useIf-None-MatchorIf-Modified-Sinceto confirm with the origin whether the content has changed. If the origin returns304 Not Modified, the cache can continue to use the original object.

CloudFront logs also useRefreshHitto indicate that the object expired, was confirmed with the origin, and the cached object continues to be used. For the specific definition, seeAWS CloudFront standard log fields.

How do you actually check whether CDN cache is hit?

The most practical method is not to keep hitting refresh in the browser, but to fix the conditions and repeatedly request the same public static asset.

Step 1: Choose a suitable URL for testing

Prefer:

  • Public CSS or JavaScript files;

  • Website logo, images, or fonts;

  • Download files that are explicitly allowed to be cached by the CDN;

  • Resources that do not require login, cookies, or authorization headers.

Don't start by testing the homepage, login page, shopping cart, or API endpoints. They may be things that should not be shared-cached in the first place.

In pursuit ofHITcaching private pages may actually cause user data leakage.

Step 2: View the complete response headers

Replace the example URL with your actual static asset:

curl -sS -D - -o /dev/null https://www.example.com/assets/app.css

Parameter meanings:

  • -D -: output response headers to the terminal;

  • -o /dev/null: do not save the response body;

  • -sS: reduce progress output but keep error messages.

Some people are used to usingcurl -Ito send a HEAD request. It is good for quickly viewing response headers, but some CDNs, origins, or cache rules handle HEAD and GET differently.

When troubleshooting real browser access, using a GET request and discarding the body is usually closer to actual conditions.

Focus on these fields:

Cache-Control: public, max-age=3600
CDN-Cache-Control: max-age=86400
CF-Cache-Status: HIT
X-Cache: Hit from cloudfront
Age: 245
ETag: "abc123"
Last-Modified: Thu, 10 Sep 2026 08:00:00 GMT
Via: ...

Step 3: Repeatedly request the same URL

for i in 1 2 3; do
  printf 'Request %s\n' "$i"
  curl -sS -D - -o /dev/null https://www.example.com/assets/app.css \
    | grep -Ei '^(cache-control|cdn-cache-control|age|via|x-cache|cf-cache-status|etag|last-modified):'
  sleep 2
done

During testing, keep these conditions consistent:

  • The full URL is the same, including case and query parameters;

  • Do not append a random timestamp each time;

  • The request method is the same;

  • Do not sometimes send cookies and sometimes not;

  • Do not actively sendCache-Control: no-cache, unless you are testing revalidation;

  • Try to make repeated requests from the same network within a short period.

Google Cloud CDN'stroubleshooting documentationalso recommends usingcurl -s -D - -o /dev/null URLto view response headers, and usingAgeand other fields to help confirm cache responses.

How should you interpret repeated test results?

The following patterns are more informative than a single result.

Repeated results

Common explanation

Next step

The first timeMISS, thenHIT, and Age increases

The node fetched it for the first time and cached it successfully

Then test other regions and key resources

Multiple consecutive requests areMISS

Object not written, cache key changing, TTL too short, or frequent eviction

Check cache headers, rules, parameters, and logs

AlwaysBYPASSorDYNAMIC

Content did not enter the shared cache under the rules

Determine whether it is by design or a configuration error

HIT, but Age occasionally resets to zero

May be switching nodes, purging cache, revalidating, or refilling

Record the response IP, node, and time at the same time

One regionHIT, another regionMISS

Different nodes have independent caches

Test repeatedly across regions

The outer layer showsHIT, while another vendor's field showsMISS

There may be multi-layer CDN or residual response headers

Use IP, CNAME, and logs to determine

The browser shows304

The browser or an intermediate cache performed conditional validation

Cannot automatically be equated with CDNHIT

Is the ideal result necessarily “all HIT”?

No.

Public versioned static resources are suitable for long-term caching, and a high hit rate is usually good; but login APIs, personal profiles, orders, shopping carts, and real-time permission data should not be shared-cached across different users in the first place.

The goal of cache optimization is not to make every URL becomeHIT, but to makecontent that should be cached reliably hit, and content that should not be shared always remain isolated.

Why does the CDN keep showing MISS?

If the same static asset still showsMISSunder repeated testing, troubleshoot in the following order.

1. The response itself does not allow shared caching

Check what the origin and CDN return:

Cache-Control: private
Cache-Control: no-store
Cache-Control: no-cache
Cache-Control: max-age=0
Set-Cookie: ...

These fields do not all have the same effect:

  • no-storemeans the response should not be stored;

  • privatemeans shared caches should not store it, and only private caches may handle it;

  • no-cachedoes not mean “absolutely cannot store,” but requires validation before reuse;

  • max-age=0makes the response immediately stale;

  • Set-Cookiecauses cache bypass under some CDNs' default policies.

Do not blindly remove these headers. First confirm whether they are protecting user state and sensitive content.

2. Each request uses a different cache key

Common causes include:

  • URL query parameters change;

  • Hostdiffers;

  • Cookies are included in the cache key;

  • Authorizationrequests are handled separately;

  • Accept-Encoding, language, or device headers participate in cache variation;

  • Varycauses the cache to be split into multiple versions.

Google Cloud CDN'show caching worksstates that the URL, query parameters, and request headers included in the cache key all affect whether an object can be reused.

A page may appear to request the same file, while the actual cache key keeps changing.

3. Cache rules do not cover this URL

Check whether the path, extension, response status code, and request method match the CDN rules.

A common case is caching only.jpg,.css,.js, while the actual file uses a dynamic path with no extension; or the rule priority is overridden by another “bypass cache” configuration.

4. TTL is too short or objects are frequently evicted

If the TTL is only a few seconds, the object may already be expired when the next request arrives.

Less popular objects may also be evicted early due to node capacity policies, so a maximum cache time does not guarantee residency time.

5. Each visit does not hit the same node

Anycast, DNS scheduling, multi-CDN, and IPv4/IPv6 differences can all cause consecutive requests to land on different nodes.

During testing, record the remote IP at the same time:

curl -sS -D - -o /dev/null \
  -w 'remote_ip=%{remote_ip} total=%{time_total}\n' \
  https://www.example.com/assets/app.css

If the response IP keeps changing, resets of Age and cache status are easier to explain.

6. You are testing HTML, APIs, or requests with identity state

Many CDNs cache static files by default but do not cache HTML and dynamic APIs by default. In this case, continuedDYNAMICorBYPASSmay be exactly the expected result.

First establish a baseline with a known cacheable public static resource, then troubleshoot dynamic content.

Why do HIT, MISS, and Age differ across regions?

CDN cache is not a single global copy.

Users in Beijing, Singapore, Frankfurt, and Los Angeles may reach different edge nodes, and each node differs in access popularity, fill time, and eviction status.

As a result, the same URL may simultaneously show:

Region

Cache status

Age

Possible situation

Beijing

HIT

850

Frequently accessed locally, cache is relatively hot

Singapore

HIT

42

Recently filled or revalidated

Frankfurt

MISS

None

First access on this node, or the object has been evicted

This is not contradictory, nor does it mean a test point is wrong.

You can first useCdnChart Website Speed Testto run multi-region tests on the same URL, check response IP, latency, and access differences by region, and then combine that with your owncurl, browser developer tools, or CDN logs to judge the cache response headers.

CdnChart's probing methodology can be found inTesting Methodology.

Note: a single cross-region test is still only a snapshot of each node at that moment. To determine whether caching is stable, it is best to fix the URL, repeatedly test in the same region, and record the time, IP, and cache status.

One HIT does not mean a high cache hit rate

A single response can only answer “did this one hit,” not “how well is the website caching overall.”

Hit rates commonly seen in CDN consoles may also be divided into:

  • Request hit rate: the proportion of requests satisfied by cache among requests that meet the statistical criteria;

  • Byte hit rate: the proportion of traffic served by cache among total transferred bytes.

For example, if many small icons are hits but a few large files frequently go back to origin, the request hit rate may look good while the byte hit rate is not high.

Conversely, one large video hit can significantly raise the byte hit rate.

In addition, different vendors may use different statistical criteria for dynamic requests, error responses, non-cacheable requests, and upper-tier cache hits. Before comparing across vendors, verify the metric definitions first; don't compare just one percentage.

What is truly worth observing over the long term is:

  • Request hit rate and byte hit rate for key static resources;

  • Origin request count, origin traffic, and origin error rate;

  • Differences in hit rates across regions, paths, and file types;

  • Changes after cache purges, releases, and version updates;

  • Whether origin load decreases reasonably as hit rates improve.

FAQ

First request MISS, second HIT — does that mean the CDN is working normally?

It usually means the current node completed cache fill, a normal cold-to-warm cache process. But you should still check the object TTL, nodes in other regions, and the long-term hit rate.

Does MISS mean CDN acceleration is not working?

No. The request has reached the CDN; it's just that the current cache layer has no reusable object.

The CDN may still provide TLS termination, connection optimization, security protection, or upper-tier caching.

Is Age 0 a HIT or a MISS?

Looking only atAge: 0is not enough to tell. It could be a cache just written or just revalidated, or it could come from another proxy.

You should check the vendor's cache status header and logs together.

Does a larger Age mean slower access?

No. Age indicates the cache age of the response, not request latency.

Performance should be measured by metrics such as DNS, connection, TLS, TTFB, and total download time.

Why can content still be received when Age exceeds max-age?

Revalidation may have occurred, stale content may be allowed, an upper-tier cache policy may exist, or themax-ageyou see is not the edge TTL ultimately used by the CDN.

You need to analyze it together withs-maxage,CDN-Cache-Control, vendor configuration, and cache status.

After a browser hard refresh it becomes MISS — is the configuration broken?

Not necessarily.

A hard refresh may carry request headers that require revalidation or bypass local cache, and may also trigger different CDN handling. When troubleshooting, use a fixed normal GET request and avoid confusing browser cache with CDN cache.

How do you confirm that a request really reached the origin?

Checking origin access logs, CDN origin logs, and origin metrics is the most reliable.

The client-sideMISScan prompt you to investigate further, but it cannot fully describe what happens inside multi-tier caching.

Summary: cache hits require a set of evidence, not a single word

Remember three core conclusions:

  1. HITmeans the current cache layer found a reusable object, but it only represents this request and this node;

  2. MISSmeans the current cache layer missed, which does not mean the CDN isn't working, nor does it necessarily prove every request goes straight to origin;

  3. Ageindicates the estimated number of seconds since the response was generated or last validated; it is not response time, nor is it inherently the remaining TTL.

When troubleshooting in practice, choose a public static asset, keep the URL and request conditions unchanged, and make three consecutive requests; record the cache status,Age,Cache-Control, response IP, and test time.

Then verify in another region and use the CDN console or origin logs to confirm whether requests truly go back to origin.

If you're still not sure which CDN the domain uses, you can first useCdnChart CDN Checkto look for vendor clues; if you want to compare access nodes and speed across regions, you can useCdnChart Website Speed Test.

Putting cache response headers together with multi-region speed test results is far more reliable than seeing oneMISSand jumping to a conclusion.

  • How to check CDN cache hit status
  • What does CF-Cache-Status HIT mean
  • What to do if CDN always shows MISS
  • What does the Age response header mean

Related posts

Website Fast on China Telecom but Slow on China Mobile: How Can You Tell If It's a CDN Issue?

Website Fast on China Telecom but Slow on China Mobile: How Can You Tell If It's a CDN Issue?

Your site loads quickly over China Telecom but slowly over China Mobile — how do you troubleshoot it? This article examines CDN node scheduling, carrier lines, DNS, IPv4/IPv6, cache HIT/MISS, and origin fetch paths, and provides same-city comparison tests and fault diagnosis methods.

16 min read
What Causes High TTFB? Should You Check the CDN or the Origin Server First?

What Causes High TTFB? Should You Check the CDN or the Origin Server First?

If your site's TTFB is high, should you check the CDN or the origin server first? This article works through a layer-by-layer diagnosis — DNS, TCP, TLS, cache HIT/MISS, the origin fetch path, server applications, and databases — and provides curl tests, a comparison matrix, and optimization methods.

14 min read
If your users are mainly in mainland China, which regions and carriers should you focus on when choosing a CDN?

If your users are mainly in mainland China, which regions and carriers should you focus on when choosing a CDN?

If your users are mainly in mainland China, which regions and carriers should you test when choosing a CDN? This article explains the testing priorities for China Telecom, China Unicom, China Mobile, and key regions, and offers a method for selecting a CDN based on user distribution, business type, and P95 performance.

14 min read
What to do when a CDN returns 502, 503, or 504? First identify whether the issue is with the edge node, origin fetch, or origin server.

What to do when a CDN returns 502, 503, or 504? First identify whether the issue is with the edge node, origin fetch, or origin server.

What do 502, 503, or 504 errors mean when a website is served through a CDN? This article examines the common causes of each status code and uses response headers, origin bypass tests, curl timing, and server logs to determine whether the fault lies at the CDN node, in the origin fetch path, or at the origin server.

12 min read