SYSTEM DESIGN · BUILDING BLOCKS · 4 OF 14

CDN: Edge Routing, Cache Keys, Origin Shield and Failover

The CDN as a component you draw and defend: how a user is routed to a nearby edge, what happens inside a point of presence, cache keys and hit ratio, tiered caching with an origin shield, push versus pull, purging and versioned URLs, dynamic acceleration and edge compute, signed URLs, what fails and how, and how to size bandwidth and origin load.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
1 / 14

Press play to hear the narration, or step through at your own pace.

Notes

The problem

The problem. A user in Pune talking to an origin in Virginia pays about two hundred milliseconds per round trip, and connecting plus TLS plus the request is three or more round trips before the first byte. The origin also serves every byte to everyone: a million users loading two megabytes each is two terabytes of egress. And any attack lands straight on your servers.

Without a CDN
  • India → US origin: ~200 ms
  • per round trip
  • TCP + TLS + request = 3+ RTTs
  • before the first byte
  • origin serves every byte:
  • 1M users × 2 MB = 2 TB
  • per page view wave
  • one DDoS hits you directly

Routing to the edge

How does the user reach a nearby edge? Two ways. DNS-based routing: your domain points at the CDN's nameservers, which answer with a nearby, healthy point of presence based on the resolver's location and current load. Or anycast: every point of presence announces the same IP address, and internet routing naturally delivers packets to the closest one. Many CDNs combine the two.

Finding the nearest edge
  • DNS-based: CDN nameserver
  • answers with a nearby PoP
  • (by resolver location, load,
  • health); short TTLs ~30-60 s
  • anycast: every PoP announces
  • the same IP; BGP routing
  • delivers you to the nearest
  • many CDNs mix both

Inside a PoP

Inside a point of presence, a layer four balancer spreads users across cache servers. TLS terminates right there, so the handshake round trips are twenty milliseconds instead of two hundred. Hot objects sit in memory and the long tail on SSD. Servers within the PoP hash the URL so each object is stored once per PoP, not once per server, which multiplies the effective cache size.

Inside a point of presence
  • L4 balancer spreads users
  • over cache servers
  • TLS terminated at the edge
  • (handshake RTTs are short)
  • cache: hot objects in RAM,
  • long tail on SSD
  • servers in a PoP hash the
  • URL so each object lives once

Cache keys

The cache key decides your hit ratio. By default it's the host, path and query string, so a tracking parameter like utm source creates a new copy for every campaign. Strip or sort query params, vary only on what really changes the response, like encoding, and never vary on cookies. Control lifetime with Cache-Control: a year with immutable for fingerprinted files, or s-maxage to cache at the CDN but not in the browser.

Cache key and headers
key = host + path + query?

Cache-Control: public,
  max-age=31536000, immutable
Cache-Control: s-maxage=60
  (CDN only), max-age=0 (browser)
Vary: Accept-Encoding

kill hit ratio: random query
params, Vary: Cookie, Set-Cookie

Origin shield

Here's the part people forget. With three hundred points of presence, a new object causes three hundred misses, each hitting the origin. Tiered caching puts an origin shield in between: every edge misses into one regional tier, and only the shield talks to the origin. Add request collapsing, where a thousand simultaneous misses for the same URL become one upstream fetch, and the origin sees roughly one request per object.

Tiered caching
  • 300 PoPs × a miss each =
  • 300 origin fetches per object
  • shield: one regional tier
  • all edges miss into
  • → origin sees ~1 fetch
  • request collapsing: 1,000
  • concurrent misses for the
  • same URL → 1 upstream fetch

Pull vs push

Two ways to fill the edge. Pull is the default: the edge fetches from the origin on the first miss and keeps the object for its TTL. There's nothing to manage, but the first user at each location waits. Push means uploading content to the CDN ahead of time. It makes sense for things you know will be hammered at a set moment, like a game patch or a launch video, at the cost of managing that storage yourself.

Pull vs push
  • pull (most common): edge
  • fetches from origin on first
  • miss, keeps it for its TTL
  • + zero ops, only hot content
  • - first user per PoP waits
  • push: you upload to the CDN
  • ahead of time
  • + no cold misses (launches,
  • big game patches, video)
  • - you manage storage + expiry

Updating files

How do you update a file cached in three hundred places? The best answer is to never update it: put a content hash in the filename, cache it for a year, and a deploy simply references the new name. For things with fixed URLs, like HTML, use short TTLs with revalidation, where the edge sends an ETag and gets a tiny 304 if nothing changed. Purges by URL or tag exist, but they take seconds to minutes to reach every edge.

Invalidation options
  • versioned URLs (best):
  • /app.3f9c1a.js, cache 1 year
  • deploy = new name, instant
  • purge by URL or tag:
  • seconds to minutes globally
  • old copy may live a bit
  • short TTL + revalidate:
  • ETag / If-None-Match → 304
  • for HTML that must stay fresh

Dynamic content

CDNs help with uncacheable traffic too. The user's TLS handshake ends at the nearby edge, and the edge forwards over warm, pooled connections across the CDN's own backbone, saving several long round trips. Popular API responses can be micro-cached for a second or two, which absorbs spikes. Edge functions can handle redirects, A/B splits, auth checks and image resizing. Video streaming works because each few-second segment is just a cacheable file.

Beyond static files
  • dynamic acceleration: TLS at
  • edge + pooled warm connections
  • over the CDN backbone to origin
  • micro-caching: cache API
  • responses 1-5 s at the edge
  • edge compute: auth checks,
  • redirects, A/B, image resize
  • video: cache HLS segments

Failure handling

Failure handling. If the origin returns errors, a stale-if-error directive lets edges keep serving the last good copy for hours. If a point of presence fails, DNS stops handing it out or anycast withdraws its route, and users land on the next nearest one. Entire CDNs have had global outages, so large sites use two CDNs with DNS steering. And keep cache keys strict, so an attacker can't get a poisoned response cached for everyone.

What fails, what happens
  • origin down: stale-if-error=
  • 86400 keeps serving old copy
  • PoP down: DNS stops handing
  • it out; anycast withdraws the
  • route → next nearest PoP
  • whole CDN down (it happens):
  • multi-CDN via DNS steering
  • cache poisoning: strict keys

Security

The edge is also your shield. Floods get absorbed across hundreds of locations before they reach you, and firewall rules run there. For private files, like paid videos, the app issues signed URLs with an expiry, and the edge checks the signature itself without calling your servers. Finally, lock the origin down so it only accepts traffic from the CDN, or attackers just go around it.

Security at the edge
  • DDoS: hundreds of PoPs absorb
  • floods far from your origin
  • WAF rules at the edge
  • signed URLs / cookies:
  • HMAC(path + expiry) checked
  • at the edge, no origin call
  • lock origin: accept traffic
  • only from the CDN

Sizing

Sizing a CDN is about bandwidth. Five million daily users at twenty megabytes each is a hundred terabytes a day. Divided by eighty-six thousand four hundred seconds and tripled for peak, that's about three and a half gigabytes a second, around twenty-eight gigabits. With a ninety-five percent hit ratio the origin only serves five terabytes a day; at ninety-nine percent, one. Byte hit ratio is the number to watch.

Sizing
5M daily users × 20 MB/day
  = 100 TB/day egress
peak ≈ 3x average:
  100 TB / 86,400 s × 3
  ≈ 3.5 GB/s ≈ 28 Gbps

hit ratio 95% → origin
  ~5 TB/day, ~1.4 Gbps peak
hit ratio 99% → 1 TB/day

cost: CDN egress < cloud egress

Say it like this

In the interview, draw users, the CDN edge, an origin shield and the origin or object store. Then give a policy per content type: fingerprinted static files cached for a year, HTML short-lived with ETags, private media behind signed URLs. Name stale-if-error for origin outages, multi-CDN if downtime is very costly, and give the egress estimate and the hit ratio you're aiming for.

In the interview
  • draw: users → CDN edge →
  • shield → origin / object store
  • cache: static + media, keys
  • normalised, immutable
  • versioned filenames
  • HTML: short TTL + ETag
  • private: signed URLs
  • failure: stale-if-error,
  • multi-CDN if critical
  • number: egress and hit ratio

Interview questions

How does a CDN route a user to the nearest edge?

Either with DNS, where the CDN's authoritative nameserver returns the IP of a nearby healthy point of presence based on the resolver's location and load, or with anycast, where all PoPs advertise the same IP and BGP routes packets to the closest one.

What is an origin shield?

A designated mid-tier cache that all edge locations fetch through on a miss, so the origin receives roughly one request per object instead of one per edge, often combined with request collapsing of concurrent misses.

How do you invalidate content on a CDN?

Prefer versioned or fingerprinted filenames with long TTLs so a deploy just references new URLs. For fixed URLs use short TTLs with ETag revalidation, and use purge by URL or tag when necessary, knowing it can take time to propagate.

What hurts a CDN's cache hit ratio?

Cache keys that include unnecessary query parameters, Vary headers on cookies or user agent, responses that set cookies, and short or missing Cache-Control lifetimes all split or shorten the cache.

Push CDN versus pull CDN?

A pull CDN fetches from the origin on the first miss and is low effort; a push CDN has content uploaded ahead of time, which avoids cold misses for predictable big launches but requires managing that storage.

Can a CDN help with dynamic, uncacheable APIs?

Yes: terminating TLS near the user and forwarding over warm, pooled backbone connections cuts round trips, short micro-caching can absorb spikes, and edge functions can handle simple logic like redirects and auth checks.

What happens if the origin goes down?

Edges keep serving cached objects until they expire, and with stale-if-error they can serve expired copies for a configured period instead of returning errors.

How do you protect private media on a CDN?

Issue signed URLs or cookies containing an expiry and an HMAC over the path, which the edge verifies without calling the origin, and restrict the origin so it only accepts requests from the CDN.