HTTP caching: browser, CDN, and origin
Caching is a contract between clients, intermediaries, and your origin. Misconfigured headers mean either stale content forever or zero cache hit rate and unnecessary load.
Cache-Control vocabulary
max-age=3600— fresh for one hour (relative to response time).s-maxage=86400— overrides for shared caches (CDNs), while browsers may still usemax-age.private— only the end user’s browser should store; CDNs must not treat as public cache.no-store— do not persist anywhere (use for highly sensitive responses).stale-while-revalidate=60— may serve stale up to 60s while revalidating in background (CDN support varies).
HTML vs hashed assets
HTML should usually be no-cache or short max-age with revalidation so users pick up new JS/CSS references quickly.
Fingerprinted assets (app.[hash].js) can be immutable with long max-age because the URL changes when content changes.
ETag and conditional requests
Strong ETags enable If-None-Match → 304 Not Modified, saving bandwidth on APIs that return unchanged JSON. Weak ETags trade precision for cheaper generation on large payloads.
CDN cache keys
Defaults often include query string—?token= can explode cache cardinality or leak personalized responses into wrong buckets. Normalize or strip sensitive query params in CDN rules.
Summary
Treat caching as product behavior: decide freshness vs cost per resource class (document, API, asset). Pair CDN rules with correct Cache-Control from the origin and verify with curl -I and real-user metrics.