Cache Control
Large-scale services run on cache.
If your web service takes a sudden flood of traffic, the first thing to do is check your cache hit ratio in the metrics. A service that can't see this number doesn't know how much it depends on cache. It varies by application, but 80% is a solid hit rate. When it drops from 80% to 60%, requests to origin double. At scale, a few percentage points can trigger an outage.
The Cache-Control header governs cache lifetime. max-age sets duration in seconds. no-cache forces revalidation every time. no-store disables caching entirely. s-maxage lets you set different TTLs for CDN and browser. What to cache and for how long is a design decision. Static assets get long TTLs. API responses get short ones. User-specific data doesn't get cached at all.
The real problem is when you want to delete cache. CDN cache lives on edge servers around the world. You hit purge, but there's a lag before every edge reflects it. Users see stale images. New CSS doesn't apply. Complaints roll in.
Phil Karlton's famous line: "There are only two hard things in computer science: cache invalidation and naming things."
The standard workaround is content hashing in filenames. Not app.css?v=1 but app.a3b2c1.css. When the content changes, the name changes, so you never need to invalidate. Personally I'm skeptical. Filenames changing on every deploy make debugging harder. Cleaning up old files is a pain. The idea that if you can't delete it you shouldn't need to—I get the logic. But it feels like trading one complexity for another.
Recently, Claude Code nuked my Cloudflare cache. I had it investigating something, hitting APIs. It executed a purge command. I stared at the screen. It was a personal site, so no real damage. But I didn't expect AI to be the one clearing my cache.
There is no silver bullet for cache. You want speed, you cache. You cache, you can't delete. The moment hit ratio drops, origin eats a DDoS. Instant death.