Tags: web-dev concept

Content Delivery Networks

Date: 2026-08-17


A geographically distributed cache that answers from near the user instead of from your origin. It buys latency, resilience and absorbed traffic — and hands you the hardest problem in computing in exchange, which is knowing when a copy is stale.


A CDN (content delivery network) is a network of servers in many locations, each holding copies of your content and serving whichever users are nearest.

WITHOUT                    WITH
user (Sydney)              user (Sydney)
  │  16,000 km               │  20 km
  ▼                          ▼
origin (London)            edge (Sydney)
  RTT ~280ms                 RTT ~5ms
                             │ only on a miss
                             ▼
                           origin (London)

The primary gain is latency, not bandwidth — the bytes travel less far, so every round trip is shorter — Latency and Bandwidth.

What it does beyond caching

  • Absorbs traffic. A campaign spike hits the edge, not your server
  • DDoS mitigation, because there is a large distributed network in front of you
  • TLS termination at the edge, so the handshake is local and fast — TLS and HTTPS
  • Compression, image transformation, format negotiation — WebP or AVIF per client, resized per device
  • Edge compute. Small functions running near the user — redirects, A/B assignment, personalisation, header rewriting — Edge Computing
  • A stable front door, so origin changes don’t move the DNS record

Cache keys, and the thing that ruins hit rates

The cache key determines what counts as “the same response”. By default it’s usually the URL — and everything you add to it multiplies the number of stored copies.

GOOD HIT RATE
key = URL

DESTROYED HIT RATE
key = URL + all query params
  ?utm_source=... creates a distinct
  entry per campaign, per variant,
  per click

key = URL + cookie
  a session cookie means a cache entry
  per user — which is no cache at all

Strip marketing parameters from the cache key. utm_*, gclid, fbclid and their kin don’t change the response, and leaving them in is one of the most common causes of a CDN that appears to be doing nothing.

Vary behaves the same way. Vary: User-Agent forks the cache per browser string — HTTP Semantics.

Static versus dynamic

STATIC        images, CSS, JS, fonts
              immutable, hashed filenames
              → cache for a year

SEMI-DYNAMIC  product pages, listings
              → short TTL, or
                stale-while-revalidate

PERSONALISED  basket, account, prices
              → don't cache, or cache
                the shell and fill client-side

The pattern that unlocks the middle row is stale-while-revalidate: serve the cached copy immediately, refresh in the background. Users always get an instant response; the content is at most one request behind.

Cache-Control: public, max-age=60,
  stale-while-revalidate=600

Invalidation

The hard half, and there are three approaches:

TTL              wait for expiry
                 simple, predictable,
                 always somewhat stale

PURGE            explicitly evict on change
                 accurate, needs a hook
                 from your CMS or deploy

VERSIONED URLS   never invalidate anything
  /app.a3f9c.js  new content = new URL
                 → cache forever, safely
                 ← the best option where
                   it applies

Versioned URLs are the only approach with no staleness problem, which is why every build tool hashes filenames. Use it for every asset you control — Caching Strategies.

Where it goes wrong

  • Caching a personalised page. One user’s basket served to everyone. The failure that ends careers, and it’s usually a missing Cache-Control: private
  • Caching a Set-Cookie response, distributing one session to many users
  • Origin assumed unreachable. Nothing stops someone hitting it directly unless you restrict it to CDN IPs or a shared secret
  • Geolocation confusion. The origin sees the edge’s IP, not the user’s. Read X-Forwarded-For or the CDN’s own header, or every visitor appears to be in one city — and analytics and geo-targeting both break
  • Purge-on-deploy that misses HTML. Assets update, pages don’t, and the new JavaScript runs against old markup

The measurement that matters

Cache hit ratio, segmented by content type. A low ratio on static assets is a configuration bug, not a tuning opportunity — and it’s usually the cache key.