📦 HTTP Headers & Caching
đź’ˇ Core idea
Caching’s whole value is skipping the network chain in TCP & TLS Handshake entirely, or at least skipping the most expensive part of it — the response body.
🏷 Header categories
- General — not tied to request or response specifically:
Date,Connection(keep-alive),Cache-Control(used in both). - Request — request context:
Host,User-Agent,Accept,Authorization,If-None-Match. - Response — response context:
Server,Set-Cookie,Location. - Entity/Representation — describe the body regardless of direction:
Content-Type,Content-Length,Content-Encoding,ETag,Last-Modified.
The split isn’t formal — it’s a hint about where a header even makes sense (Content-Length is meaningless without a body).
đź—„ Cache-Control
max-age=N— seconds the response is considered fresh; during that window the browser serves the cached copy instantly, without contacting the server at all.no-cache— misleading name: caching is allowed, but every serve requires revalidation with the server via a conditional request (see ETag below).no-store— no caching at all, in any form.private/public— cacheable only in the user’s browser / cacheable anywhere along the chain (including CDNs/proxies).
Key distinction: no-cache = “cache it, but always revalidate”; no-store = “don’t cache it at all”.
ETag and conditional requests
- First response:
200 OK+ body +ETag: "abc123"(a fingerprint of this specific version of the resource). - Cached copy is stale /
no-cache— the browser sendsIf-None-Match: "abc123"instead of blindly re-downloading. - Server compares: match →
304 Not Modified, no body (saves the entire response body’s worth of traffic); no match →200 OK+ new body + newETag.
If-Modified-Since/Last-Modified follow the same principle by timestamp instead of hash — coarser (second-level precision), but doesn’t require computing a hash server-side.
304 responses have nothing beyond the headers — no body, no extra structure.
Where caching sits in the chain
Caching kicks in before the network: if max-age hasn’t expired, no connection opens at all (no DNS, no TCP, no TLS). no-cache/304 is a partial win — the round trip still happens, but the most expensive part (the response body) is saved.
🌍 Cache locations and strategies
Three points along the request path, each a potential “warehouse” holding a ready copy — from closest/fastest to farthest/slowest:
- Browser cache — a copy on the user’s disk/memory. No network at all.
- CDN — a copy on a server geographically close to the user (not the site’s origin server). Needs the network, but a shorter path. Only used if the response is marked
Cache-Control: public;privateallows a copy only in the browser cache, never on a CDN/shared proxy. - Origin server — where the code and data actually live. The farthest option, reached only if there’s nowhere closer to get a copy.
Strategies
- cache-first — if something’s in the cache, serve it, never touch the network (zero checks, not “constant revalidation”). Safe for resources that never change under the same URL (a hashed filename — a change produces a new filename/URL, so the old cached copy can never become “wrong”).
- network-first — try the network for a fresh copy first; the cache is only a fallback when the network is unavailable. For frequently-changing data (a feed, an exchange rate) where freshness matters.
- stale-while-revalidate — hybrid: serve whatever’s cached immediately (even if stale), and in parallel, in the background, fire a normal network request to refresh the cache for next time. The user never waits on the network, but doesn’t always see the newest version either.
HTTP & Network TCP & TLS Handshake — what caching lets you skip CORS — the other browser-side network gate browser