Level 2 · 20 min
CDN & HTTP Cache
HTTP caching is built into the web's architecture. Cache-Control headers, ETags, and CDN edge nodes reduce origin server load and improve latency for users globally.
Cache-Control Headers
Cache-Control is both a request and response header — request Cache-Control directives (no-cache, no-store, max-stale=N) can override response caching behavior in some CDN configurations; understand your CDN's precedence rules. s-maxage applies exclusively to shared caches (CDNs, reverse proxies) and takes precedence over max-age when both are present. stale-while-revalidate=N: the CDN serves the stale response and triggers a background revalidation request to origin for up to N seconds past max-age expiry. stale-if-error=N: serve the stale response for up to N seconds when origin returns a 5xx error — essential for resilience during origin outages. immutable (RFC 8246): instructs the browser to skip conditional revalidation entirely during the max-age window, not just the TTL check — saves a round trip for static assets with content-hashed URLs. must-revalidate: once expired, must not serve stale even under stale-if-error conditions. Vary: Accept-Encoding causes the CDN to store separate cache entries per encoding variant (gzip, br, identity) — correct behavior, but avoid Vary: Cookie on CDN-cached responses since every unique cookie value generates a distinct cache entry.
ETags and Conditional Requests
ETag is a fingerprint (hash or version token) of the response content. The client stores the ETag value. On subsequent requests: If-None-Match: "abc123". If content is unchanged, the server returns 304 Not Modified with no body — saving bandwidth proportional to response body size, but not eliminating the network round trip. For large API responses (10KB+ JSON), ETag-based conditional GETs reduce bandwidth by 90%+ while still using 1 RTT. Weak ETags (W/"abc123") indicate semantic equivalence — same logical data, possibly different byte representation (e.g., different JSON key ordering). Strong ETags indicate byte-for-byte identity. CDNs treat weak ETags differently: some CDNs will not cache responses with weak ETags. Last-Modified/If-Modified-Since is the timestamp-based alternative — simpler to implement but limited to 1-second granularity. The known race condition: two updates within the same second appear identical to a client using If-Modified-Since; it returns 304 for the second update, serving stale content. Production insight: the Vary header instructs CDNs and shared caches to maintain separate cache entries for each distinct value of the named request header — Vary: Accept-Encoding is safe and expected, but Vary: Accept-Language or Vary: Cookie on a CDN-cached endpoint multiplies storage cost by the cardinality of distinct header values observed; a single endpoint with 20 language variants and Vary: Accept-Language generates 20 distinct cache entries per edge PoP, each needing independent warmup, dramatically increasing the effective cache miss rate after a deployment or purge event.
CDN Edge Caching
CDN architecture layers: edge PoP (Point of Presence) is the user-facing cache node at the network edge. Origin Shield (Cloudflare: Argo Smart Routing/Tiered Cache; CloudFront: Origin Shield; Fastly: Shielding) is a regional mid-tier cache between edge PoPs and origin. Without Origin Shield: 300 edge PoPs independently miss the same uncached item, generating 300 simultaneous origin requests. With Origin Shield: all PoPs within a region route cache misses through one regional node — origin receives at most one request per region. Cache key customization: CDNs default to URL as cache key. Cloudflare Cache Rules support query string normalization (sort params alphabetically to unify ?a=1&b=2 and ?b=2&a=1), stripping of analytics params (utm_source, fbclid), and varying on custom headers. Surrogate-Key (Fastly) or Cache-Tag (Cloudflare) headers in origin responses enable tag-based purging: a single API call purges all edge nodes caching responses tagged product:1001 simultaneously across 300+ PoPs — more targeted and instant than URL-based purges.
Code example
# API response: short cache, revalidate
Cache-Control: public, max-age=60, stale-while-revalidate=30
ETag: "abc123def456"
# Static JS bundle: immutable, 1 year cache
Cache-Control: public, max-age=31536000, immutable
# URL: /static/main.a1b2c3.js (content hash in filename)
# Private user data: never CDN cache
Cache-Control: private, no-store
# CDN behavior: product page
# First request → CDN miss → origin returns:
Cache-Control: public, s-maxage=3600, max-age=0, stale-while-revalidate=60
# CDN caches for 1 hour. Browser revalidates every time.
# Next 3599 requests from edge → no origin hit