Website problems
CDN never serving from cache
A content delivery network is useful because it answers from a node near the visitor instead of forwarding to your origin. When its cache status header reports a miss on every request, none of that is happening: every visitor's request crosses the network to your origin exactly as it did before, with an extra hop added. The edge is working correctly and has been given nothing to store, which is almost always a directive the origin is sending.
What a persistent miss means
The edge received the request, found nothing stored for it, and forwarded it to the origin.
A miss on a first request to a cold node is normal — the entry has to be created somehow.
A miss on every request, including repeated ones to the same URL from the same region, means nothing is being stored.
Which is different from the edge being slow or misconfigured: it is doing what it was told, and it was told not to keep anything.
The consequence is origin load unchanged, latency slightly worse, and the CDN bill unchanged.
The usual causes, in order of frequency
The origin sending a directive forbidding shared caching — `private`, `no-store`, or `no-cache` applied site-wide rather than to the pages that need it.
A `Set-Cookie` header on every response, which many edges treat as making the response uncacheable.
A `Vary` header listing something near-unique per visitor, so every request is its own variant and no two ever match.
A cache key configuration including the full query string, where tracking parameters make every visit unique.
An authentication header on requests that could otherwise be cached, which some edges exclude by default.
Why the cookie case is so common
A session framework that starts a session on every request sends a cookie on every response, including to visitors who never signed in.
Edges treat that as a signal the response is personalised, which is a reasonable default and wrong for a static marketing page.
The fix is starting sessions lazily — only when something is actually stored in one — which is a framework setting on most stacks.
It also removes a cookie from every anonymous visit, which is worth doing for its own sake.
This single change frequently takes a hit rate from near zero to most requests.
What should and should not be cached at the edge
Static assets with fingerprinted names: the longest lifetime available, because a new build produces a new filename.
Public pages that are the same for everyone: a real lifetime, with revalidation if the content changes often.
Pages that differ per visitor: not at the edge, and the directive should say so explicitly rather than relying on a cookie heuristic.
API responses carrying per-person data: never, and that is a data-separation question rather than a performance one.
The mistake in both directions is applying one policy to everything, which either caches what it must not or caches nothing.
How to check it yourself
`curl -I https://example.com/some-asset.js` twice and read the edge's cache status header on the second response.
A miss on both is the finding; a miss then a hit is the edge working.
Read the Cache-Control and Set-Cookie headers on the same response, which is usually where the answer is.
Check a static asset and a page separately, since they frequently have different policies and only one is broken.
Check from a second region if you can, since a hit is per node and a single node tells you about that node.
How VeriFixScan detects it
`performance.cdn_cache_status` reads the hit and miss headers really returned by the edge, which is this problem directly.
`performance.static_cache` reads Cache-Control, ETag and Last-Modified for static resources, which is what the edge is obeying.
`performance.cache_control` reports the policy on the entry document.
`infrastructure.cdn` and `infrastructure.cache_state` report whether a CDN is in the path at all and what state it reports.
`cookies.inventory` reports the cookies set in real response headers, which is where the cookie cause becomes visible.
What this costs while it persists
Origin capacity, since every request reaches it — which is the cost that appears as an outage under load rather than as slowness.
Latency for every visitor, who now pays a hop to the edge plus the full round trip to the origin.
Resilience: a cached edge serves stale content during an origin outage, and an empty one has nothing to serve.
And the CDN spend, which buys none of the above while the configuration stands.
Frequently asked questions
- Is a cache miss a problem?
- One is not — an entry has to be created somehow. A miss on every repeated request to the same URL means nothing is being stored, which is the finding.
- Why would a cookie stop my CDN caching?
- Many edges treat a Set-Cookie header as a signal the response is personalised. A framework starting a session on every request sends one to every anonymous visitor.
- Should I just force caching at the edge?
- Only for responses that are genuinely the same for everyone. Overriding the origin's directives on pages that differ per visitor is how one person's data reaches another.
Sources
Related
VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.
Scan a website