System Design · Medium
Design a content delivery network (cdn)
Cache content at the edge, invalidate on demand, and route users to the nearest PoP.
Requirements
What the system must do, and how well it must do it.
Functional
Cache static assets (images, JS, CSS, video chunks) at edge PoPs.
Anycast DNS routes users to the nearest healthy PoP.
Cache invalidation: purge by URL, tag, or wildcard (propagate < 30 sec).
Origin shield: a mid-tier cache between edge and origin.
HTTPS termination, compression (gzip/brotli), and HTTP/2/3 at the edge.
Non-functional
Cache hit ratio > 95% for cacheable content.
Edge latency p99 under 50 ms (cached), 200 ms (origin shield hit).
Invalidation propagated globally within 30 seconds.
Handle 10M RPS aggregate across PoPs.
Estimation
Back of the envelope numbers that drive the design.
100 PoPs worldwide, 10 TB cache each = 1 PB edge cache.
Origin shield: 10 regional shields × 100 TB = 1 PB.
Invalidation: 1M purges/day. Propagation via gossip or pub/sub.
DNS: 1M zones, TTL 30 sec for anycast failover.
Architecture
Design decisions
Anycast routing
The same IP prefix is announced from multiple PoPs. BGP routes the user to the nearest PoP (by AS-path length). Health checks withdraw the prefix from unhealthy PoPs. DNS-based fallback: a short TTL (30 sec) A/AAAA record per PoP; the client picks the lowest-latency IP from the response.
Cache hierarchy
Edge cache (small, hot objects) → Origin shield (larger, regional) → Origin (source of truth). The shield absorbs cache misses from multiple edge PoPs, reducing origin load. Cache key = normalized URL (sorted query params, stripped tracking params). Vary headers (Accept-Encoding, Accept-Language) create multiple variants.
Invalidation
Purge API accepts URL, tag (surrogate-key), or wildcard. The control plane publishes invalidation events to a gossip protocol or pub/sub (Kafka). Each PoP receives and evicts matching entries from its cache. Invalidation latency target: < 30 sec global. Tag-based invalidation is preferred (for example, product:123 purges all product images).
Edge compute
Run lightweight code at the edge (Workers, Lambda@Edge): A/B testing, auth, redirects, image resizing, personalization. Execution time limit (for example 50 ms CPU). Isolate untrusted code (V8 isolates, WebAssembly). Logs and metrics streamed to central observability.
Questions and answers
Follow-ups an interviewer is likely to ask. Try answering before you open each one.
How do you handle cache stampede on a cold key?
Request collapsing: the first miss acquires a lock; subsequent requests wait for the same fetch. Or use stale-while-revalidate: serve stale content while asynchronously revalidating.
What if the origin is down?
Serve stale content (if configured) with a Warning: 110 header. The shield and edge can serve stale for hours. Health checks route around the origin shield if it fails.
How do you measure cache efficiency?
Hit ratio (hits / (hits + misses)), byte hit ratio (bytes served from cache / total bytes), and origin offload ratio. Per-PoP and per-content-type breakdowns.