All posts
Performance3 min readWatchFor Team

Caching Explained: browser, CDN and server caches

Caching is the closest thing the web has to free speed: store a result once, reuse it many times. Here are the three layers of caching, how each works, and the one hard part — invalidation.

Caching Explained: browser, CDN and server caches

There's an old joke that there are only two hard problems in computer science: cache invalidation, naming things, and off-by-one errors. The joke survives because caching is everywhere — it's the single most effective way to make things fast — and getting it right is genuinely tricky. Let's make it simple.

What caching is

Caching means storing the result of expensive work so you can reuse it instead of redoing it. Compute a page once, serve the stored copy a thousand times. Fetch an image once, reuse it on every visit. The fastest work is the work you don't repeat.

On the web, caching happens at three layers, each closer to the user than the last.

The three layers

LayerWhere it livesCaches
BrowserThe user's deviceAssets, so repeat visits are instant
CDN / edgeServers near usersContent, served without touching your origin
Server / appYour backendComputed results, query results, rendered pages

Browser cache

The browser stores assets (images, CSS, JS) locally, so a returning visitor doesn't re-download them. You control this with HTTP cache headers (Cache-Control, ETag) — telling the browser how long it may reuse a file.

CDN / edge cache

A CDN caches your content at locations near users. The first request fetches from your origin; everyone after is served from the nearby edge — fast for the user, and a huge load off your origin.

Server / application cache

On your backend, you cache the expensive stuff: database query results, rendered pages, API responses (often in an in-memory store). This is what slashes your TTFB — instead of rebuilding a page on every request, you serve a cached copy.

TTL: how long to cache

Every cache entry has a lifespan — a TTL (Time To Live):

  • Long TTL → faster (fewer recomputes/refetches), but changes take longer to show.
  • Short TTL → fresher, but less benefit.

The classic pattern: cache static assets (with content-hashed filenames) for a very long time, and cache dynamic content for short, sensible windows.

The hard part: invalidation

Here's the catch. The flip side of caching is stale content: you update something, but caches keep serving the old version until they expire.

Cache invalidation is the hard problem — knowing when to throw away a cached copy. Cache too long and users see stale data; cache too short and you lose the benefit. The common solution is content-hashed filenames (e.g. app.a1b2c3.js): when the content changes, the filename changes, so the old cache is naturally bypassed.

For pages and APIs, you'll either set short TTLs or actively purge the cache when the underlying data changes.

A monitoring gotcha

Caching can hide problems: a cached page can look perfectly healthy while your origin is broken underneath. That's why it's worth occasionally checking the origin directly (with no-cache requests) so a stale cached copy doesn't mask an outage your users will hit once the cache expires.

The bottom line

In one line
WhatStore a result once, reuse it many times.
Three layersBrowser (device), CDN (edge), server (backend).
TTLLong = fast but stale-prone; short = fresh but less gain.
Hard partInvalidation — use content-hashed filenames and purging.

Caching is the closest thing to free speed on the web — it's how fast sites stay fast under load. Cache at all three layers, set sensible TTLs, and have a plan for invalidation, and you get the speed without serving stale content.

Related: How to speed up your website, What is a CDN?, TTFB.

Share this article