Content Delivery Network (CDN)

Edge caching, origin shielding, push vs pull, cache invalidation, signed URLs.

Building Block Intermediate
6 min read
cdn edge caching
Companies this resembles: Cloudflare · Akamai · Fastly · CloudFront · BunnyCDN

Use cases#

A CDN moves content closer to users by replicating it across geographically distributed POPs (points of presence). The classic use cases:

  • Static asset delivery — JS bundles, CSS, images, video. The mature, no-brainer use case.
  • Video streaming — segment-based delivery (HLS, DASH) where every 2-10 second .ts chunk is cached at the edge.
  • API acceleration — caching GET responses, terminating TLS, running JWT validation at the edge.
  • DDoS absorption — the CDN’s huge anycast capacity soaks attacks before they reach the origin.
  • Edge compute — Cloudflare Workers, AWS Lambda@Edge, Fastly Compute@Edge — running app logic geographically close to users.

Functional requirements#

  • Cache content at edge POPs keyed by URL (and optionally headers like Accept-Language).
  • Forward cache misses to a configured origin server.
  • Respect Cache-Control, ETag, and Last-Modified semantics.
  • Support purge/invalidation via API.
  • Optionally sign URLs to gate access.
  • Optionally compress, resize, or transform content at the edge.

Non-functional requirements#

  • Latency: edge hit p99 under 50 ms globally — physically achievable because every metro has a POP within 20 ms.
  • Hit ratio: 90%+ on static workloads is typical; high-traffic CDNs (Netflix, YouTube) hit 95-99%.
  • Throughput: aggregate Tbps. Cloudflare’s published peak is around 200 Tbps; Akamai reports similar.
  • Availability: a CDN is the most-replicated tier of the stack — 99.99% is the floor.

High-level design#

┌────── origin (us-east-1) ──────┐
│ app servers + database │
└────────────────▲────────────────┘
│ miss / revalidate
┌────── origin shield (regional) ─────┐
│ intermediate cache, dedups misses │
└────────────────▲────────────────────┘
┌────────────┬────────────┬──┴────────┬────────────┐
POP-SFO POP-DFW POP-IAD POP-FRA POP-NRT
│ │ │ │ │
clients clients clients clients clients
(anycast routes each to nearest POP)

User requests anycast to the nearest POP. POP cache hit → respond. Miss → ask the regional origin shield, which dedups concurrent misses from many POPs into one origin request. Hit at the shield → respond and populate the POP. Miss at the shield → fetch from origin, populate everything on the way back.

Detailed design#

Push vs pull#

Pull CDN — POPs lazily fetch on first request; missing content is served slow but populates automatically. Common for web assets, images, video. Defaults: Cloudflare, Fastly, CloudFront.
Push CDN — origin uploads content explicitly before users request it. Predictable latency from the first request; explicit storage cost. Common for static-site hosts (Netlify Edge, Vercel), large software downloads.

In practice, most CDNs operate pull mode with explicit prefetch APIs for hot content that you can’t afford to slow-cache.

Cache keys#

The cache key is the URL plus a configurable set of headers / cookies. Surprisingly subtle:

  • Include Accept-Encoding to keep gzip, br, and identity copies separate.
  • Include Accept-Language only if the response actually varies on it (otherwise you split the cache and tank hit ratio).
  • Strip query params that don’t affect the response (utm_source, fbclid) before cache lookup.
  • Personalized responses (Cookie: session=...) bypass cache entirely unless you key on a hashed user-tier.

Invalidation#

The two hard problems in computer science: naming things, cache invalidation, and off-by-one errors. CDN approaches:

  • TTL expiry — default and cheapest. Set Cache-Control: public, max-age=60 and live with 60 s of staleness.
  • Versioned URLsapp.abc123.js (hash in the filename) is immutable; deploy = new URL = no invalidation needed. The dominant pattern for static assets.
  • Purge API — explicit DELETE /url. Most CDNs propagate purges in 5-30 s; Fastly famously purges globally in ~150 ms via varnish.
  • Cache tags / surrogate keys — tag each response with product-42, then purge by tag (PURGE product-42) to invalidate every URL that depends on it. Cloudflare and Fastly both offer this.

Origin shielding#

Without shielding, a cold object at 100 POPs causes 100 origin requests on first access. The origin shield is one regional POP designated as the only one that talks to origin — every other POP misses up to the shield. Reduces origin load by ~100×.

Signed URLs#

For paywalled video, private downloads, time-limited access:

https://cdn.example.com/video.mp4?Expires=1715800000&Signature=HMAC(secret, "video.mp4|1715800000")

The CDN validates the signature at the edge — bad signature → 403, good signature → cached delivery. The origin sets the policy and computes the signature; the CDN enforces it without phoning home.

Stale-while-revalidate#

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

The edge serves cached content for 60 s. Between 60 s and 660 s, it serves the stale copy immediately and fetches a fresh one in the background. Users never wait on revalidation; content is “fresh enough”. Widely supported and underused.

Edge compute#

The CDN’s POP runs untrusted JS/WASM with millisecond cold starts. Use cases:

  • Auth/JWT validation before the request hits origin.
  • A/B test bucketing.
  • Geolocation-based redirects.
  • Personalization (Edge Side Includes for cached pages + per-user fragments).
  • Full apps (Cloudflare’s Workers ecosystem).

Trade-offs#

Other axes:

  • Cache hit ratio vs personalization — every Vary: Cookie header destroys cacheability. Keep cookies off paths you want cacheable.
  • TTL length — short TTL costs origin bandwidth; long TTL extends the staleness window. Stale-while-revalidate is the right answer for most pages.
  • Push vs pull — push is predictable, pull is operationally simpler. Hybrid (pull + prefetch hot content) wins in practice.
  • Multi-CDN — for global availability or for negotiating leverage. Adds complexity in cache-key consistency and purge fan-out. Major SaaS companies (Shopify, Twilio) typically run multi-CDN with NS1 or Cedexis steering.

Real-world examples#

  • Netflix Open Connect — Netflix built its own CDN. Cabinet-sized boxes deployed inside ISPs; each holds ~280 TB of video. Cache hit ratio reportedly exceeds 95%.
  • Cloudflare — 300+ POPs, anycast routing, free tier handles ~20% of all websites. Workers add edge compute.
  • Akamai — the original commercial CDN (1998). Still the largest by POP count; specialized for video and enterprise.
  • Fastly — Varnish-based, instant (sub-second) global purge. Famous for the 2021 outage that took down Reddit, Spotify, and the NYT for an hour.
  • CloudFront — AWS’s CDN, deeply integrated with S3 and Lambda@Edge. Used by Hulu, Slack, and most AWS-native companies.
  • BunnyCDN — budget CDN popular with bootstrappers; pull-based with edge rules for image transformation.
  • DNS — anycast routing steers users to the nearest POP.
  • Distributed Cache — a CDN POP is a giant distributed cache with HTTP semantics.
  • Blob Store — the typical origin for static assets and video segments.
  • Load Balancers — each POP fronts a small fleet behind a local LB.
Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.