HTTP caching and cache headers
How browsers, CDNs and proxies decide what to cache: Cache-Control directives, max-age and s-maxage, ETags and conditional requests, immutable assets with fingerprinted URLs, stale-while-revalidate, Vary, private versus shared caches, and purging.
Reading is half of it. See this used in a real interview: walk through Design a URL Shortener →
The cheapest request is the one that never reaches your servers. HTTP has a built-in caching system used by every browser, CDN and proxy, controlled by a few response headers. Getting them right can remove most of your traffic and make pages load instantly; getting them wrong serves one user's private data to another or leaves stale content stuck for days. Interviewers expect you to know the basics whenever a CDN appears in your design.
Cache-Control
The main header. Common directives:
| Directive | Meaning |
|---|---|
max-age=N | fresh for N seconds in any cache |
s-maxage=N | fresh for N seconds in shared caches (CDNs), overriding max-age there |
public | may be stored by shared caches |
private | only the user's browser may store it |
no-cache | may store, but must revalidate with the server before each use |
no-store | never store anywhere (sensitive data) |
immutable | will never change; do not even revalidate |
stale-while-revalidate=N | serve stale for up to N seconds while fetching a fresh copy in the background |
stale-if-error=N | serve stale for up to N seconds if the origin fails |
Note the common confusion: no-cache does not mean "do not cache"; no-store does.
Revalidation with ETags
When a cached copy is stale, the cache can ask the server whether it changed instead of downloading it again:
- The server sends an
ETag(a version identifier, often a hash) orLast-Modified. - The cache sends
If-None-Match: <etag>(orIf-Modified-Since). - If unchanged, the server replies
304 Not Modifiedwith no body.
This saves bandwidth, not round trips. ETags also enable optimistic concurrency for writes (If-Match). See API design.
Patterns by content type
| Content | Headers | Why |
|---|---|---|
Static assets with hashed names (app.3f9a1c.js) | public, max-age=31536000, immutable | the URL changes when content changes, so cache forever |
| HTML pages | public, max-age=0, s-maxage=60, stale-while-revalidate=300 or no-cache | always fresh-ish; CDN absorbs load |
| Public API responses (popular lists) | public, s-maxage=30, stale-while-revalidate=60 | short CDN caching of shared data |
| Personalised responses | private, max-age=0 or no-store | never in shared caches |
| Images and video segments | long max-age with versioned URLs | huge bandwidth savings |
| Redirects for short links | 301 cached long, or 302 with a short max-age | trade analytics accuracy for load |
The fingerprinted URL pattern (cache forever, change the name on deploy) is the most effective caching technique on the web. See Design Netflix and Design YouTube.
Vary
Vary tells caches which request headers change the response (for example Vary: Accept-Encoding for compressed versus plain). Varying on high-cardinality headers like Cookie or User-Agent effectively disables shared caching, since every user gets a separate entry. Normalise at the CDN instead (device class rather than full user agent).
Never leak private data
The worst caching bug is a CDN storing a response with one user's data and serving it to others. Prevent it:
- Mark anything personalised
privateorno-store. - Configure the CDN to bypass caching when an
Authorizationheader or session cookie is present, unless explicitly allowed. - Separate public and personalised endpoints; fetch personal data client-side after a cached public shell.
Purging and invalidation
- Versioned URLs avoid invalidation entirely.
- Purge APIs remove a URL or a tag (surrogate keys) from the CDN in seconds, for content that must change at a fixed URL.
- Short TTLs with stale-while-revalidate give near-fresh content with high hit rates and no purge logic.
See CDN and edge and caching.
Browser and service worker caches
Browsers also have memory and disk caches, plus service workers that can implement custom strategies (cache first, network first) for offline apps. See offline-first apps and sync.
In the interview
When you add a CDN, say what it caches and for how long: "static assets are fingerprinted and cached for a year; the redirect responses are cached at the edge with a short s-maxage and stale-while-revalidate; personalised feed responses are private." For Design a URL Shortener, discuss 301 versus 302 and its effect on click analytics.
Checklist
- Fingerprinted static assets with a one-year max-age and immutable.
- Short s-maxage plus stale-while-revalidate for shared dynamic content.
- ETags for cheap revalidation.
privateorno-storefor anything personal; CDN bypass on auth.- Careful Vary; no Vary on Cookie for shared content.
- Versioned URLs or tag-based purges for invalidation.