patternjavascriptModerate
CDN configuration: cache key design and purge strategy for correct invalidation
Viewed 0 times
CDNcache keycache invalidationCloudflare Workerssurrogate keysCDN purgecache fragmentation
Problem
CDN cached responses serve stale HTML after a deployment. Alternatively, the CDN cache key includes unnecessary request headers (Accept-Encoding, User-Agent) causing cache fragmentation and low hit rates.
Solution
Design cache keys deliberately and use deployment-triggered purges.
// Cloudflare Workers: normalize cache key
export default {
async fetch(request) {
const url = new URL(request.url);
// Remove tracking params from cache key
url.searchParams.delete('utm_source');
url.searchParams.delete('fbclid');
const cacheKey = new Request(url.toString(), {
headers: { 'Accept-Encoding': 'br' } // normalize to Brotli
});
const cache = caches.default;
let response = await cache.match(cacheKey);
if (!response) {
response = await fetch(request);
await cache.put(cacheKey, response.clone());
}
return response;
}
};
// Purge on deploy via API
curl -X POST https://api.cloudflare.com/client/v4/zones/{id}/purge_cache \
-d '{"purge_everything":true}'
// Cloudflare Workers: normalize cache key
export default {
async fetch(request) {
const url = new URL(request.url);
// Remove tracking params from cache key
url.searchParams.delete('utm_source');
url.searchParams.delete('fbclid');
const cacheKey = new Request(url.toString(), {
headers: { 'Accept-Encoding': 'br' } // normalize to Brotli
});
const cache = caches.default;
let response = await cache.match(cacheKey);
if (!response) {
response = await fetch(request);
await cache.put(cacheKey, response.clone());
}
return response;
}
};
// Purge on deploy via API
curl -X POST https://api.cloudflare.com/client/v4/zones/{id}/purge_cache \
-d '{"purge_everything":true}'
Why
Cache key fragmentation (a different cached copy per User-Agent or Accept-Encoding variant) tanks hit rates because most requests miss. Normalizing the cache key and stripping tracking parameters consolidates variants into a single cached response.
Gotchas
- Vary: Accept-Encoding in response headers causes CDNs to cache separate copies per encoding — normalize at the CDN instead
- Purge-everything on every deploy is expensive for large sites — use surrogate keys/tags for surgical purging
- Stale-While-Revalidate at the CDN level serves cached responses while revalidating in the background
- CDN caches are regional — a purge must propagate to all PoPs, which can take seconds
Code Snippets
Verify CDN cache status with curl
# Check CDN cache status for a URL
curl -I https://example.com/app.js | grep -E '(cf-cache-status|x-cache|age):'
# cf-cache-status: HIT — served from CDN cache
# age: 3600 — cached for 3600 secondsContext
When CDN hit rates are low or users see stale content after deployments
Revisions (0)
No revisions yet.