system-design/cdn-edge.md

24. CDN & Edge Computing

A CDN (Content Delivery Network) is a geographically-distributed cache + acceleration tier between your origin and your users. Done well, it serves 90%+ of bytes from the edge — cutting latency, bandwidth costs, and o…

~6 min read·updated 5/29/2026

24. CDN & Edge Computing

A CDN (Content Delivery Network) is a geographically-distributed cache + acceleration tier between your origin and your users. Done well, it serves 90%+ of bytes from the edge — cutting latency, bandwidth costs, and origin load.

24.1 What a CDN does

  • Cache static assets (JS, CSS, images, video) close to users.
  • Cache dynamic responses (API responses with appropriate headers).
  • TLS termination at the edge — handshake closer to user.
  • DDoS protection (Cloudflare/Akamai absorb attacks before origin).
  • WAF (Web Application Firewall) at the edge.
  • Bot management.
  • HTTP/2 / HTTP/3 termination.
  • Compression (Brotli, gzip).
  • Image / video transformations at the edge.
  • Edge compute (Cloudflare Workers, Lambda@Edge, Vercel Edge Functions).

24.2 Why edge wins

  • Latency: 5-50ms to nearest CDN PoP vs 100-300ms cross-continent to origin.
  • Bandwidth: tier-1 bandwidth at scale is far cheaper for the CDN; you'd pay much more directly.
  • Reliability: PoP failures → routes to next-nearest automatically (anycast).
  • Origin shielding: 1M users hit 50 PoPs hit 1 origin per cache key.

24.3 How a request flows

User → DNS → CDN edge IP (anycast) → nearest PoP
PoP cache?  yes → serve
            no → fetch from origin (or shield) → cache → serve

Cache hit ratio is the critical metric. 95%+ for static; 70-90% for cacheable dynamic; 0-50% for non-cacheable APIs.

24.4 Cache control headers (recap)

  • Cache-Control: public, max-age=31536000, immutable — cache for 1 year, never revalidate. Use for fingerprinted assets (app.[hash].js).
  • Cache-Control: private, max-age=60 — browser only, 60s.
  • Cache-Control: no-store — never cache.
  • Cache-Control: stale-while-revalidate=60 — serve stale up to 60s while async revalidating.
  • Vary: Accept-Encoding — cache different copies for different encodings (gzip vs br).
  • Vary: Accept-Language — different cache per language. Be careful: high cardinality kills hit ratio.

Edge-specific

  • Surrogate-Control (CDN-specific override of Cache-Control): tell the CDN to cache longer than the browser.
  • CDN-Cache-Control (proposed standard, similar idea).

24.5 Cache key design

Default cache key = full URL + selected headers + query string. Customize:

  • Strip tracking params (utm_*) → don't fragment cache.
  • Sort query params → consistent keys.
  • Hash long keys.
  • Include Authorization header? No, unless you want per-user caching (rarely).

24.6 Cache invalidation

The eternal hard problem.

Strategies

  • TTL: tolerate staleness up to T. Simplest; works for most static.
  • Versioned URLs (app.v123.jsapp.v124.js): no invalidation needed; old cache ages out. Standard for assets.
  • Purge API: tell CDN "evict this URL" — Cloudflare, Fastly, Akamai all expose this.
  • Surrogate keys / cache tags: tag responses; purge by tag (Fastly's killer feature). Used to invalidate "all pages tagged with article-42."
  • Soft purge: mark stale; serve stale with revalidation header.

Invalidation latency

Purge propagation is not instant. Cloudflare ~30s; Fastly ~150ms. Plan for it.

24.7 Static vs dynamic content

Static

HTML, CSS, JS, images, fonts, video. Cache forever with versioned URLs. 99%+ hit ratio.

Semi-dynamic

Product pages, marketing pages, blog posts, search results that don't depend on the user. Cache with appropriate TTL or surrogate keys.

Dynamic / user-specific

Logged-in dashboards, user-specific feeds. Generally bypass CDN (Cache-Control: private, no-store). Or cache per-user with a private cache (browser only).

Edge-cacheable JSON

Public API responses (e.g., GET /products). Add cache headers; CDN absorbs the load. Big lever often missed.

24.8 Origin shielding

When you have 50 PoPs and 1 cache miss → 50 fetches to origin. Mitigate:

  • Tiered cache: PoP misses go to a regional shield → only one fetch from shield to origin.
  • All major CDNs offer this; Cloudflare's "Argo Tiered Cache," Fastly's "Origin Shielding."

24.9 CDN-side compute (edge functions)

Run code at the edge (V8 isolates, WebAssembly).

  • Cloudflare Workers: V8 isolates; fast cold start (sub-ms); 50ms CPU limits; KV / Durable Objects for state.
  • Lambda@Edge / CloudFront Functions: AWS counterpart.
  • Vercel Edge Functions / Deno Deploy / Fastly Compute@Edge: similar.

Use cases:

  • A/B test routing.
  • Auth checking before letting requests through.
  • Header rewriting.
  • Geo-aware routing.
  • API mocking / response shaping.
  • Image transformations.
  • LLM-driven personalization at the edge.

Limits: short execution time, restricted runtime (no Node.js APIs), memory caps.

24.10 Image and video at the edge

Images:

  • Resize / format-convert (WebP, AVIF) on demand.
  • Cache the variants.
  • Tools: Cloudflare Images, Imgix, Cloudinary, AWS Lambda + CloudFront.

Video streaming:

  • HLS or DASH adaptive bitrate.
  • Encode multiple bitrate ladders → cache segments at edge.
  • Players adapt to network conditions.
  • Live: low-latency HLS / WebRTC for sub-second; standard HLS ~10s latency.

(See chapter 34 — YouTube.)

24.11 Anycast

Same IP advertised from many PoPs; BGP routes to nearest. Heart of CDN routing.

Failure of a PoP → BGP withdraws → next-nearest PoP serves seamlessly.

Used by: Cloudflare, Google Public DNS, Fastly. Not all CDNs (CloudFront uses geo-DNS instead, with regional edge caches).

24.12 DDoS mitigation

CDN absorbs L3/L4 floods at the network edge:

  • SYN flood, UDP amplification, etc.
  • Massive aggregate capacity (Tbps).
  • Auto-mitigation (Cloudflare Magic Transit, AWS Shield).

L7 attacks (HTTP floods, slowloris):

  • Behavioral fingerprinting.
  • Rate limiting.
  • Bot detection (TLS fingerprint, JS challenge, captcha).

24.13 Cost model

CDNs charge by:

  • Bandwidth out (cents per GB; varies by region).
  • Requests (sometimes; usually low).
  • Add-ons (WAF, image opt, edge compute) per use.

Most apps cut bandwidth bill by 70-90% by adding a CDN. Origin only sees cache misses.

24.14 Common CDNs

  • Cloudflare: huge network, free tier, edge compute, security focus.
  • Fastly: developer favorite, real-time purge, surrogate keys, VCL.
  • Akamai: oldest, biggest enterprise CDN.
  • AWS CloudFront: integrated with AWS; Lambda@Edge.
  • Google Cloud CDN: integrated with GCP; uses Google's network.
  • Bunny.net, BunnyCDN: cheap, simple.
  • Vercel / Netlify: dev-focused, integrated with their hosting.

24.15 When CDN doesn't help

  • Personalized responses everywhere: nothing to cache.
  • Tiny user base in one region: a CDN PoP isn't faster than your origin.
  • Strong consistency needed on every read: CDN serves stale by design.

For internal tools or B2B SaaS in one region, CDN is mostly about TLS termination and DDoS, not caching.

24.16 Hard problems

Multi-region CDN write

Static assets are easy (push). Dynamic content + origin in one region = high write latency from far edges. Mitigation: multi-origin or Active-Active with conflict resolution.

Cache poisoning

Bad input poisoning a shared cache key (HTTP request smuggling, web cache deception). Mitigation: strict header validation, normalized cache keys.

Cache stampede after purge

You purged a hot URL; 1000 PoPs miss simultaneously; origin gets hit hard. Mitigation: stale-while-revalidate, single-flight at the shield, longer warm-up.

Personalization vs cacheability

Common pattern: serve a "skeleton" page from CDN; hydrate user-specific bits client-side via API call. Best of both worlds.

24.17 Design checklist

For each endpoint:

  • Is this cacheable? (deterministic for given URL?)
  • What's the freshness tolerance? (TTL)
  • Per-user? (no edge cache; maybe browser private)
  • Vary headers needed? (Accept-Language, Accept-Encoding)
  • Purge mechanism on change? (versioned URL or purge API)
  • Fingerprint static assets at build time.
  • Compress (Brotli for text).

Key takeaways

  • CDN = highest-leverage performance + cost win. Use it from day one.
  • Static assets: versioned URLs, year-long TTL, immutable.
  • Dynamic JSON: cache aggressively with explicit headers when public.
  • Edge compute lets you move auth, routing, transforms close to user.
  • Anycast + tiered cache + shield = how CDN scales globally.

// 1 view

main
UTF-8·typescript