X-Cache
The HTTP X-Cache unofficial response header indicates whether a CDN or caching proxy served the response from cache or fetched the content from the origin server.
Usage
The X-Cache header is added by CDN providers
and Caching proxies to signal cache status. When
a request reaches a cache node, the node checks its
stored content. If a fresh copy exists, the
response is served directly from cache and marked
as a HIT. If no cached copy is available, the
node fetches the content from the origin server and
marks the response as a MISS.
This header is not part of the official HTTP specification. CDN providers such as AWS CloudFront, Fastly, Varnish, Akamai, and Azure CDN all use the X-Cache header, though the exact values and formatting differ between providers. Cloudflare uses a separate Cf-Cache-Status header for the same purpose.
Values
HIT
The HIT value means the response was served
from the cache without contacting the origin
server.
MISS
The MISS value means the cache did not have a
stored copy and the response was fetched from the
origin server. The content is typically cached for
subsequent requests after a MISS.
The remaining values come from nginx's
proxy_cache, which exposes the
$upstream_cache_status variable for logging and
for an X-Cache style header added through
add_header. The large CDNs stay with the HIT
and MISS families above.
BYPASS
The BYPASS value means the cache was
intentionally skipped through a matching
proxy_cache_bypass condition.
EXPIRED
The EXPIRED value means the stored entry had
passed its freshness lifetime and the request went
to the origin for a full response.
STALE
The STALE value means an outdated stored copy was
served under a proxy_cache_use_stale condition,
such as an origin error or timeout.
UPDATING
The UPDATING value means an outdated stored copy
was served while the cache fetched a fresh response
in the background, enabled through the updating
parameter of proxy_cache_use_stale.
REVALIDATED
The REVALIDATED value means an expired entry was
confirmed still valid by the origin through a
conditional request, enabled with
proxy_cache_revalidate on.
Example
AWS CloudFront includes a descriptive format with
the provider name. Hit from cloudfront means the
resource was served from the CloudFront cache.
Miss from cloudfront means no cached copy existed
and the response was fetched from the origin
server.
X-Cache: Hit from cloudfront
X-Cache: Miss from cloudfront
X-Cache: RefreshHit from cloudfront
RefreshHit from cloudfront means the cached copy
had expired and CloudFront revalidated the object
with the origin before serving. Error and redirect
responses produce Error from cloudfront and
Redirect from cloudfront.
Fastly, Varnish, and other caching proxies use a
shorter format. HIT and MISS carry the same
meaning as above.
X-Cache: HIT
X-Cache: MISS
Akamai and Azure CDN use a third format with a
TCP_ prefix. TCP_HIT means the edge served the
object from cache and TCP_MISS means the edge
fetched it from the origin. Akamai exposes the value
when the request carries its debug Pragma headers.
Squid-based proxies use a related style with the
responding hostname appended, such as
MISS from proxy.example.re.
X-Cache: TCP_HIT
Many CDN setups have multiple cache layers: a
local edge node close to the visitor and a regional
shield cache closer to the origin. When both values
are MISS, the resource was not found at either
layer, and the origin server fulfilled the request.
X-Cache: MISS, MISS
Three comma-separated values represent three cache tiers. In this example, the first tier missed, the second tier had a cached copy, and the third tier (edge) still had to fetch from the previous tier. This pattern is common in multi-tier CDN architectures.
X-Cache: MISS, HIT, MISS
Some responses observed in the wild append a counter
after HIT. The format is undocumented by any CDN
vendor, and the counter is read as the number of
times the cached entry has been served since being
stored.
X-Cache: HIT: 2