Networking
HTTP caching
How Cache-Control, ETag and Vary let browsers and CDNs skip work, with a standard pattern of fingerprinted assets for a year and revalidated HTML.
HTTP caching is set entirely by headers, and both browsers and CDNs follow them. Getting the headers right is one of the cheapest performance wins available. The same headers, set carelessly, can also leak one user's data to another.
Concept
Before you start: a cache keeps a copy of a response so the next request can skip the trip to the origin. A validator is a version fingerprint, such as an ETag, that lets a cache check whether its copy is still current.
Cache-Control
Cache-Control is the main control. Its directives are:
max-age=31536000, immutable: cache for a year and never revalidate. Use this for fingerprinted assets such asapp.3f9a1c.js, whose URL changes when the content does.no-cache: the response may be stored, but the cache must revalidate with the server before each use. Good for HTML.no-store: never store it. Use this for sensitive responses such as bank statements.privateorpublic:privatemeans only the user's browser may cache it, not shared caches such as CDNs. Anything personalized must beprivate.s-maxage=60: a separate TTL for shared caches. The CDN can keep a copy for 60 seconds while browsers revalidate.stale-while-revalidate=30: serve the stale copy for up to 30 seconds while refetching in the background.
Walking through it: a conditional request
Validators make revalidation cheap. The server sends an ETag (a version fingerprint) or a Last-Modified timestamp. When the cached copy expires, the client asks with a conditional request:
GET /v1/catalog HTTP/1.1
If-None-Match: "a1b2c3"
HTTP/1.1 304 Not Modified
ETag: "a1b2c3"
Cache-Control: max-age=60A 304 has no body. If the catalog is 400 KB, revalidation costs one round trip and a few hundred bytes, not 400 KB. The cache keeps its copy and refreshes its timer.
Vary
Vary tells caches which request headers change the response. Vary: Accept-Encoding means gzip and Brotli versions are cached separately.
Be careful with Vary: Cookie or Vary: User-Agent on a CDN. Each distinct value creates a separate cache entry. With cookies, that is almost one entry per user, which destroys the hit rate.
Browser cache vs CDN cache
The browser cache serves one user and saves the whole network trip. A CDN serves everyone near a point of presence and saves the trip to your origin.
A common pattern pairs the two:
- HTML:
Cache-Control: public, max-age=0, s-maxage=60. The CDN caches for a minute, and browsers always check. - Static assets: fingerprinted URLs with a one-year
immutablelifetime.
index.html public, max-age=0, s-maxage=60 → CDN keeps it 60 s
app.3f9a1c.js public, max-age=31536000, immutable → cached for a yearCommon mistakes
- Marking personalized pages
public. A shared cache can serve one user's page to another. - Using
Vary: Cookieon a CDN. The hit rate collapses to almost nothing. - Caching HTML for a year. Users then keep an old page that points at removed assets.
- Using
no-storeeverywhere. It disables caching entirely. Reserve it for sensitive responses.
Check yourself
- Why can a 304 response save bandwidth for a 400 KB catalog? The client sends its ETag, the server confirms it still matches, and no body is sent.
- Why is a fingerprinted asset safe to cache for a year? Its URL changes whenever its content changes, so an old copy is never served for new content.
Key takeaways
Cache-Controlsays who may store a response and for how long.privateands-maxageseparate browsers from CDNs.ETagplusIf-None-Matchturns a full download into a cheap 304 check.Varymust name only headers that really change the response. Cookies inVarydestroy cache hit rates.- Fingerprinted assets with
immutable, and revalidated HTML, is the standard pattern.
Further learning
Next, see how cookies, CORS and streaming shape what browsers send and receive, in cookies, CORS and streaming.
Related
HTTP/1.1, HTTP/2 and HTTP/3
The protocol of the web. Separates HTTP's meaning (methods, status codes, caching) from its wire format, and shows how each version fixes the latency problem of the one before.
CDNs and the edge
Serve content from points of presence near users. A CDN cuts latency, absorbs attacks and cuts bandwidth costs, and its cache keys, headers and purge rules decide how well it works.
Requests, methods and status codes
What an HTTP request and response look like on the wire, which methods are safe and idempotent, and which status codes tell clients and proxies what to do next.