CachingCDN CachingMedium⏱️ ~2 min

How CDN Cache Keys and Freshness Control Work

A Content Delivery Network (CDN) cache key determines whether two requests can share the same cached response. The base key typically combines scheme, host, path, and a normalized subset of query parameters. CDNs then add selected HTTP headers (via Vary) to create variants. For example, a URL like https://example.com/product?id=123&utm_source=email becomes a cache entry that might also vary by Accept-Encoding header to store both gzip and brotli compressed versions. Every additional dimension in your cache key multiplies the number of cached variants and fragments your cache memory, directly reducing hit ratio. Freshness is governed by HTTP caching semantics. The Cache-Control directive s-maxage tells shared caches (CDNs) how long to consider an object fresh, independent of max-age for browser caches. When an object becomes stale, the CDN can revalidate using conditional requests with ETag (If-None-Match) or Last-Modified (If-Modified-Since) headers. If content has not changed, the origin returns HTTP 304 with no body, refreshing the CDN's freshness timer while transmitting only headers (typically under 1 KB versus potentially megabytes for the full response). Modern extensions like stale-while-revalidate allow the CDN to serve the stale object immediately while asynchronously fetching a fresh copy, cutting tail latency by 100 to 200 milliseconds during revalidation. Production systems must balance cache key cardinality against hit ratio. Including full User-Agent strings in cache keys can create thousands of variants for a single URL, dropping hit ratios from 90% to under 40%. Well-optimized implementations whitelist only essential query parameters (stripping tracking tokens like utm_source), normalize headers to coarse categories (device class rather than full User-Agent), and strip all cookies except those that genuinely change content (like locale). Amazon CloudFront customers commonly see byte hit ratios above 90% for static assets by fingerprinting filenames (style.a3f2b1c9.css) and setting s-maxage to 31536000 seconds (one year), knowing the URL itself guarantees immutability.
💡 Key Takeaways
Cache keys combine scheme, host, path, normalized query parameters, and selected headers; each additional dimension multiplies variants and reduces hit ratio proportionally
The s-maxage directive controls freshness for shared CDN caches independently from browser max-age; typical values range from 60 seconds for dynamic content to 31536000 seconds (one year) for immutable assets
Revalidation with ETag or Last-Modified returns HTTP 304 responses (headers only, typically under 1 KB) when content unchanged, refreshing freshness without retransmitting the full body
Including full User-Agent strings or unbounded query parameters in cache keys can fragment cache into thousands of variants, dropping hit ratios from 90% to below 40% in production
Fingerprinting immutable assets (hash in filename like bundle.7f3a2b.js) enables year-long TTLs because the URL itself changes when content changes, eliminating purge dependency
The stale-while-revalidate extension serves cached content immediately while asynchronously refreshing in background, reducing revalidation latency by 100 to 200 milliseconds at percentile 95
📌 Examples
Netflix static web assets use fingerprinted URLs (main.a4f3c2.js) with Cache-Control: public, max-age=31536000, s-maxage=31536000, immutable achieving 95%+ byte hit ratios and eliminating revalidation traffic
Amazon CloudFront customers strip tracking parameters by whitelisting only product-relevant query params (id, variant) and ignoring utm_source, utm_campaign, reducing key cardinality from thousands to dozens per URL
A news site using stale-while-revalidate with 30 second s-maxage serves articles within 20 milliseconds from edge while asynchronously checking origin, versus 150 milliseconds with synchronous revalidation
← Back to CDN Caching Overview