CDN
A network of caches near your users that absorbs most of your traffic, if you tell it exactly what's safe to cache.
The story
On Christmas Day 2015, Steam, Valve's game store, was hit by a large traffic flood. In response, a caching configuration change was rolled out. The new configuration cached pages that should never have been cached: account pages, with personal details on them.
For roughly an hour and a half, some users who opened their account page were served someone else's cached page instead. Valve later said around 34,000 users' information may have been shown to others: billing and email addresses, purchase history, and the last digits of card numbers.
The CDN worked exactly as configured. It took a response and served it again to the next person who asked for the same URL. That's what makes a CDN fast, and it's also what makes a wrong cache rule a privacy incident.
A CDN is the cheapest scaling win available. This page is about getting that win and keeping private data out of the cache.
The idea
A CDN is a fleet of caching servers in hundreds of locations (points of presence, or PoPs) close to users. Users connect to the nearest PoP. If it has the response, it's served from there, and your origin never sees the request.
What you get:
- Latency: bytes and the TLS handshake travel tens of kilometres, not thousands (Data Locality).
- Offload: with a 95% hit ratio, the origin serves 1 in 20 requests. The 9 GB/s of thumbnails in Estimation becomes about 450 MB/s at the origin.
- Protection: the CDN's capacity absorbs DDoS floods, and WAF rules run at the edge.
- Origin shield: a middle tier, so a miss in 200 PoPs becomes one request to your origin, not 200.
Pull vs push. Almost everyone uses pull: the edge fetches from the origin on the first miss and caches it. Push (you upload content to the CDN in advance) suits large files you know will be requested, such as a game patch or a video release.
The cache key and the private-data rule
The CDN serves a cached response to any request with the same cache key, by default the URL (host + path + query string). Anything not in the key is ignored. That includes the cookie that says who the user is.
Defensive rules that would have prevented the story:
- The origin marks every personalised response
privateorno-store. Don't rely on the CDN's path rules alone. - Default to not caching paths that have a session cookie or an
Authorizationheader unless they're explicitly marked public. - Put personalised data in API calls the page makes after it loads (cached nowhere), and cache the page shell.
Freshness and invalidation
- Static assets: fingerprint the filename and cache for a year. Deploys change the URL, so nothing ever needs purging.
- HTML and API responses: short
s-maxage(the shared-cache TTL) plusstale-while-revalidate, so users get an instant answer while the edge refreshes. - Purges: by URL or by surrogate key/tag (e.g. purge everything tagged
product-42). Good for "the price was wrong". Bad as the only invalidation strategy.
Beyond caching: CDNs also speed up uncacheable requests (TLS terminates near the user, and the CDN keeps warm connections to your origin), and run code at the edge (Cloudflare Workers, Lambda@Edge) for redirects, A/B splits and auth checks.
Cheat sheet
| Question | Answer |
|---|---|
| What to put on a CDN | All static assets, media, public pages and public API responses |
| Never at the edge | Anything that differs per user: Cache-Control: private / no-store |
| Cache key | URL + only the headers that really vary the response (language, device) |
| Static asset TTL | 1 year + fingerprinted filenames |
| Dynamic but public | Short s-maxage + stale-while-revalidate |
| Fix a wrong response now | Purge by URL or surrogate key |
| Many PoPs missing at once | Origin shield |
| Healthy hit ratio | 90%+ for static content. Track it per path. |
| Big planned release | Pre-warm or push to the CDN |
| Bonus | DDoS absorption, WAF, edge TLS, edge compute |
Say it in the interview
"Everything static goes through the CDN with fingerprinted filenames and a one-year TTL. Public product pages get a 60-second s-maxage with stale-while-revalidate, and price changes purge by product tag. Anything personalised is marked private at the origin, so even a bad CDN rule can't cache it. An origin shield keeps misses from 200 PoPs down to one request to us."
Go deeper
- SD 3 · Q21 — Why CDNs Exist: the chain of whys.
- SD 2 · Chapter 22 — Design a Global CDN: how a CDN itself is built.
- Caching and Invalidation: the same staleness problems, one layer further in.