Design problems
Classic building blocksHardSDE-3 30 min

Design a content delivery network

Asked at
AmazonGoogleJioHotstarMicrosoftNetflix

The interviewer asks

“Design a content delivery network that serves images, video segments and static files for many customer websites from servers close to users. Customers should be able to purge content and see traffic stats.”

What a strong answer looks like

A strong answer starts with the request path: DNS or anycast steers the user to a nearby point of presence (PoP), an edge cache serves hits from RAM/SSD, misses go to a regional mid-tier (shield) cache and only then to the customer's origin. The deep dives are request routing (GeoDNS vs anycast, health-aware steering), the cache hierarchy and request coalescing that protect the origin, cache keys and invalidation (TTL, purge fan-out, versioned URLs), and TLS at the edge. Add the control plane: config and certificates pushed to thousands of servers, plus a log pipeline for billing and analytics. Numbers to quote: a 95%+ hit ratio, edge latency under 20-30 ms for most users, and tens of Tbps of egress across ~200 PoPs.

Concepts to mention

Points of presence near usersGeoDNS vs anycast routingTiered caching with an origin shieldRequest coalescingConsistent hashing inside a PoPCache key designTTL, purge and versioned URLsStale-while-revalidate / stale-if-errorTLS termination with SNIStaged config rolloutHit ratio and origin offload

1 Requirements

Functional

  • Serve customer content (images, JS/CSS, video segments, downloads) from edge servers near the user
  • Fetch from the customer's origin on a cache miss and cache by HTTP cache rules or customer config
  • Purge or invalidate content by URL, by prefix or by tag within seconds
  • Terminate TLS with the customer's certificate (custom domains)
  • Give customers per-domain traffic, hit-ratio and error dashboards and usage-based billing
  • Basic edge protection: rate limits and blocking of bad IPs

Non-functional

  • Latency: time to first byte under 30 ms p50 for cache hits for users in covered cities
  • Availability: 99.99%+; a PoP failure must move traffic away within ~1 minute
  • Scale: ~200 PoPs, peak egress ~50 Tbps, ~20M requests/s globally
  • Cache hit ratio: 95%+ by bytes for static and VOD content
  • Purge propagation: global purge completes in under 5 s (p99 < 30 s)
  • Origin offload: origin should see well under 5% of user requests

Out of scope (say it out loud)

  • Full WAF rule engine and bot detection
  • Edge compute / serverless functions (mention as extension)
  • Live video packaging and transcoding

2 Estimates

Global request rate~20M req/s peakLarge CDNs serve tens of millions of HTTP requests per second; assume 20M/s for sizing
Per-PoP load~100k req/s, ~250 Gbps20M ÷ 200 PoPs; egress 50 Tbps ÷ 200 = 250 Gbps, busy metros carry 5-10x more
Servers per PoP~10-100One modern edge server can push ~50-100 Gbps of cached video with kernel TLS and NVMe; a 250 Gbps PoP needs ~5-10 for egress, more for redundancy and small-object CPU
Edge cache size~100-500 TB per PoPe.g. 20 servers × 24 NVMe drives × ~1 TB usable; hot working set lives in ~1-2 TB RAM per PoP
Origin traffic~1M req/s total20M req/s × 5% miss; with a shield tier, the origin sees only shield misses, often < 1%
Access logs~14 TB/hour raw at peak (~2-3 TB compressed)20M req/s × ~200 bytes per log line = 4 GB/s × 3,600 s ≈ 14 TB/hour; logs compress 5-7x

3 API

EndpointWhat it does
GEThttps://cdn.customer.com/{path}End-user content request served by the edge
POST/v1/distributionsCustomer creates a distribution: hostname, origin, cache rules, certificate
POST/v1/distributions/{id}/purgePurge by URL list, prefix or cache tag; returns purge_id
GET/v1/purges/{purge_id}Purge progress: PoPs done vs total
GET/v1/distributions/{id}/stats?from&toRequests, bytes, hit ratio, status codes by time bucket

4 Data model

distribution_configPostgres (source of truth) + edge KV snapshot
distribution_id (PK)customer_idhostnames[]origincache_rulestls_cert_idversion

Edits go to Postgres; a versioned snapshot is pushed to every edge server's local KV so the request path never calls a central DB.

edge_cacheRAM + NVMe on each edge server
cache_key (hash of host + path + selected query/headers) → headersbodyexpires_attags

LRU or segmented LRU per tier; within a PoP, consistent hashing picks which server owns an object so it is stored once per PoP.

certificatesSecrets vault + encrypted edge store
cert_idhostnamescert chainprivate key (encrypted)not_after

Loaded by SNI at handshake time. Keys may be kept in an HSM-backed keyless service for strict customers.

purge_requestsPostgres + Kafka
purge_id (PK)distribution_idtypetargetscreated_atpops_acked

Purge events fan out via a pub/sub bus; each PoP acks so progress can be shown.

request_logsKafka → ClickHouse / S3
tspopdistribution_idstatusbytescache_statuslatency_msclient_asn

Columnar store for fast per-customer aggregates; raw logs to S3 for customer export and billing audit.

5 Architecture

CLIENTSEDGESERVICESASYNCDATAEXTERNALresolve hostnameHTTPS GETon misson miss, coalescedconfig, purgestorepublish changeconfig, purgespurgesaccess logsaggregatearchivestats queryCustomer ConsoleEnd usersEdge PoP (L4 LB +cache)GeoDNS / AnycastControl Plane APIRegional Shield CacheConfig + Purge BusLog Pipeline (Kafka)Config DB (Postgres)Analytics (ClickHouse)Raw Logs (S3)Customer Origin
ClientEdge / gatewayService / workerQueue / streamCacheDatabase / storageAI / modelThird partyrequestasync (event / queue)

Hover a box to highlight its connections.

6 Request flows

Serve an image (hit and miss)

  1. 1User's browser resolves img.shop.com, which is a CNAME to the CDN; GeoDNS (or anycast IP) returns the nearest healthy PoP, e.g. Mumbai
  2. 2TLS handshake terminates at the edge using the certificate selected by SNI; TLS session resumption makes repeat visits cheap
  3. 3An L4 load balancer in the PoP hashes the cache key so the request lands on the server that owns this object
  4. 4Edge server looks up the cache key in RAM, then NVMe: on a hit it returns the bytes in a few ms
  5. 5On a miss it asks the regional shield (e.g. Mumbai shield for all of South Asia); concurrent misses for the same key are collapsed into one upstream request
  6. 6If the shield also misses, it fetches from the customer origin, stores the object, and streams it back while caching at both tiers
  7. 7Edge writes an access log line (cache_status=HIT/MISS) to a local buffer that ships to Kafka

Purge a URL

  1. 1Customer calls POST /purge with a URL list or cache tag; control plane writes purge_requests and returns purge_id
  2. 2Control plane publishes the purge to the bus; every PoP and shield subscribes
  3. 3Each server marks matching keys as invalid (soft purge: stale, revalidate on next request) and acks
  4. 4Control plane counts acks; when all PoPs ack (usually < 5 s) the purge is complete; slow PoPs are retried or drained

7 Deep dives

Request routing: GeoDNS vs anycast

Two ways to send a user to a nearby PoP. GeoDNS: the CDN's authoritative DNS looks at the resolver's IP (or the EDNS Client Subnet hint) and returns the IP of the best PoP, using a map built from latency measurements, PoP load and health. It allows fine control (shift 10% of Delhi traffic to Mumbai) but depends on DNS TTLs (typically 30-60 s) and on the resolver being near the user, which fails when users use 8.8.8.8 without ECS. Anycast: every PoP announces the same IP prefix via BGP, and the internet routes each user to the 'nearest' PoP in BGP terms. Failover is fast (withdraw the route) and it absorbs DDoS naturally because attack traffic spreads across PoPs, but BGP path is not always lowest latency and load steering is coarse. Many CDNs combine them: anycast for DNS and DDoS absorption, DNS-based steering for HTTP traffic. Inside the PoP, an L4 load balancer (ECMP + consistent hashing, like Google Maglev or Facebook Katran) spreads connections without breaking them when servers are added.

Cache hierarchy, keys and origin protection

With 200 PoPs, a flat design means each object can miss 200 times at the origin. A two-tier hierarchy fixes this: edges miss to a few regional shield caches, and only shields talk to the origin, so a new object causes about one origin fetch per region. Inside a PoP, consistent hashing on the cache key routes each object to one server, so the PoP stores one copy, not twenty, and hit ratio rises. Request coalescing (collapsed forwarding) is essential: if 10,000 users ask for a new video segment in the same second, only one request goes upstream and the others wait for that response. The cache key is usually scheme + host + path + a whitelist of query params; including the full query string or Cookie header destroys hit ratio. Vary headers (like Accept-Encoding) must be normalised to a small set. Storage uses RAM for the hottest objects and NVMe for the long tail, with admission policies (do not cache an object until its second request) to stop one-hit wonders evicting useful content. Stale-while-revalidate and stale-if-error let the edge serve slightly old content while refreshing or while the origin is down.

Invalidation and config propagation

Purge has to reach thousands of servers fast. The control plane writes the request durably, then publishes it on a global pub/sub fabric (Kafka per region, or a gossip/fan-out tree). Each server applies it and acks. Purge by URL is a direct key delete. Purge by prefix or tag cannot scan 100 TB; instead servers keep a tag index (tag → keys) or store a per-tag/per-distribution generation number and treat older objects as invalid when read. Soft purge (mark stale and revalidate with If-None-Match) is safer than hard delete because the origin is not stampeded. The best practice for customers is versioned URLs (app.3f9a1c.js) with long TTLs, so most deploys need no purge at all. Config changes (new cache rule, new certificate) use the same channel with a monotonically increasing version: servers apply versions in order and the control plane can do staged rollouts, first one canary PoP, then 10%, then all, because a bad config pushed globally is the classic way CDNs cause worldwide outages.

TLS at the edge and custom domains

Every customer hostname needs a valid certificate at every PoP. The edge picks the certificate by SNI during the handshake, from a local store synced from a central vault. Automated issuance (ACME / Let's Encrypt) with renewal ~30 days before expiry avoids the most common outage: expired certificates. TLS 1.3 and session resumption cut handshake round trips, which matters a lot on high-latency Indian mobile networks where one RTT can be 80-150 ms. HTTP/2 and HTTP/3 (QUIC) at the edge reduce head-of-line blocking on lossy networks. The edge keeps warm, long-lived connections to shields and origins, so a user in Patna pays the handshake cost only to the nearby PoP, not to a far-away origin. For banks and others that do not want to share private keys, a keyless model lets the edge call the customer's key server only for the signing step.

8 Trade-offs

Push vs pull CDN

Pull (fetch on first miss) needs no customer work and caches only what is popular; first requests are slower. Push (customer uploads to the CDN) suits large, predictable files like game patches or a big OTT release, but wastes storage on unpopular objects. Most general CDNs are pull with optional prefetch.

More PoPs vs bigger PoPs

Many small PoPs cut latency (more cities, including Tier-2 India) but each has a smaller cache and lower hit ratio. Fewer, larger PoPs have better hit ratios and are cheaper to run. Common answer: big PoPs in metros plus small embedded caches inside ISPs (like Netflix Open Connect) for heavy video.

Long TTLs vs freshness

Long TTLs maximise hit ratio and origin offload but make updates depend on purge. Short TTLs keep content fresh but raise origin load. Use long TTL + versioned URLs for assets, short TTL + stale-while-revalidate for HTML and APIs.

9 Bottlenecks

Flash crowd on a new object

A cricket highlight goes viral and 1M users request it within a minute. Without coalescing, every edge server misses at once and the origin melts. Fix: request coalescing at edge and shield, the shield tier, and pre-warming objects the customer knows will be hot.

Hot object on one server

Consistent hashing puts one hot object on one server, which may not have enough NIC capacity. Detect hot keys and replicate them to several servers in the PoP (or serve from RAM on all servers), trading a little storage for spread load.

Log volume

Terabytes of logs per hour cannot be shipped raw in real time. Aggregate counters at the edge every 10-60 s for dashboards and billing, and batch-compress raw logs to S3 for customers who need them.

10 Failure handling

A PoP goes down

Health checks from many vantage points detect it within seconds. Anycast routes are withdrawn and GeoDNS stops returning that PoP; users move to the next-nearest PoP. Neighbour PoPs need headroom (~30-40%) to absorb the shift.

Customer origin is down

Serve stale content (stale-if-error) for cached objects, return a cached error page with a short TTL for others, and apply circuit breaking toward the origin so retries do not finish it off when it recovers.

Bad config pushed

Staged rollout with automatic health gates (error rate, CPU) stops a bad config at the canary PoP. Every server keeps the last known good config and can roll back locally without the control plane.

11 What impresses

  • Explaining why anycast helps DDoS absorption and fast failover but gives coarse load control
  • Using request coalescing plus a shield tier to cut origin load from N PoPs to ~1 per region
  • Explaining tag purge using generation numbers instead of scanning caches
  • Calling out cache admission (second-hit) to protect the cache from one-hit wonders
  • Mentioning that global config pushes are a top cause of CDN outages and need canaries
  • India angle: ISP-embedded caches and HTTP/3 for lossy mobile networks

12 Mistakes

  • Drawing a CDN as 'one cache in front of the origin' without routing or tiers
  • Using the full URL with all query params and cookies as the cache key
  • Ignoring the thundering herd when a popular object expires
  • Proposing a central database lookup on every edge request
  • Saying purge is instant without explaining how it reaches thousands of servers
  • Forgetting TLS certificates for custom domains

13 Follow-ups

Q1How would you serve personalised or authenticated content through the CDN?
Q2How would you detect and mitigate a DDoS at the edge?
Q3How does a CDN help with live video during a cricket final?
Q4How would you bill customers accurately when logs arrive late or are lost?
Q5How would you add edge compute (functions at the PoP)?
Q6What changes if a customer needs data to stay inside India?

Saved on this device. Create a free account to keep it on every device.

Practise this with Sam

A real mock interview, out loud, with an honest scorecard. Free to start.

Start free