Home › High-Level Design › Content Delivery Networks (CDN)
C

Content Delivery Networks (CDN)

If your design serves images, video, JS bundles, or any static-ish content to users in more than one city, a CDN is almost always part of the answer. I have watched candidates build a gorgeous service layer and then quietly assume the browser in Jakarta talks to a server in Virginia for free. It does not. Light is slow and distance costs you, so that round trip lands near 250ms before your server does one useful thing. A CDN is the first thing I reach for to fix that, and the first thing a sharp interviewer checks you understand.

High-Level DesignIntermediate11 min read

If you remember five things

Two wins, three sharp edges. Everything below defends these five.

  1. Two wins, not one. Lower latency for users (serve from a nearby edge) and lower load on your origin (the edge absorbs 90 to 99 percent of requests). Name both or you sound shallow.
  2. Hit rate is the dial. Everything (origin fleet size, bandwidth bill, p99 tail) moves with your cache hit rate, and hit rate is set by your TTL and your cache key.
  3. Versioned URLs beat purging. Content-hashed filenames with a one-year TTL mean you never invalidate. The short-TTL HTML just points at new files.
  4. Cache keys are a correctness problem. Too loose and you serve one user's cookie to everyone. Too tight and your hit rate collapses to zero.
  5. Misses are the dangerous path. A miss is slower than no CDN for that one request, and a cold cache after a purge can stampede your origin. Design so you rarely purge.

1The core idea#

Keep copies of your content close to the people who want it. That is the whole mental model.

  • A CDN is a fleet of caching servers spread across many physical locations, called edge locations or points of presence (PoPs).
  • Big providers run 300 or more PoPs across 100-plus cities.
  • A request gets served from the PoP nearest the user instead of from your single origin far away.
  • Your origin (an S3 bucket, a web server, an object store) stays the source of truth. The CDN holds temporary copies.
  • A user in Mumbai hits a Mumbai edge, a user in São Paulo hits a São Paulo edge, and both feel fast even though your origin sits in one data center in Oregon.

Two things make this work, and both matter for the interview:

  • Geography. A round trip from Sydney to Virginia is roughly 200ms of pure network latency before you do anything useful. Sydney to a Sydney edge is single-digit milliseconds, call it 5ms. For a page that loads 40 assets, that per-asset gap compounds into the difference between snappy and sluggish, even with HTTP/2 multiplexing, because TLS setup and connection warm-up still pay the distance tax.
  • Offload. Every request the edge serves from its cache is a request your origin never sees. A good config absorbs 90 to 99 percent of traffic for static content. At 99 percent offload your origin sees 1 request for every 100 the edge handles, which is the difference between running 4 origin servers and running 400.
The one line that scores

A CDN buys two separate wins at once: lower latency for users and lower load on your origin. They are related but not the same thing, and strong candidates name both out loud. Say only "it makes things faster" and I have you pegged as surface-level.

2How it works#

Follow one file through the system and the mechanics fall out.

  • A user asks for logo.png.
  • DNS resolves your CDN hostname to the IP of a nearby edge (usually via anycast or geo-aware DNS).
  • The edge checks its local cache.
  • Fresh copy present: that is a cache hit and it responds immediately.
  • Nothing fresh: that is a cache miss, so it fetches from origin, stores a copy, then responds. The next user in that region gets a hit.
flowchart LR A[User in Mumbai] --> B[Nearest Edge PoP] B -->|cache hit| A B -->|cache miss| C[Origin Server] C --> D[(Object Store)] C --> B B --> A
The hit path never touches origin. Only the miss walks all the way back to the origin and object store, and that one trip is what you spend the rest of the design minimizing.

The whole game is maximizing hits and keeping cached copies correct. Four mechanics control that:

  • TTL (time to live). Your origin sends headers like Cache-Control: max-age=86400, telling the edge "good for a day" (86400 seconds). After it expires the edge revalidates.
  • Cache key. The edge decides what counts as "the same request." By default it is the URL, but you can include or exclude query strings, headers, and cookies. Get this wrong and you either cache too little (every variation is a miss) or serve the wrong thing to someone.
  • Revalidation. With ETag or Last-Modified the edge asks origin "has this changed?" and origin can reply 304 Not Modified with no body. A cheap way to confirm freshness without re-downloading a 2MB image to learn it is unchanged.
  • Invalidation / purge. When you ship new content you tell the CDN to drop the old copy. Section 5 covers why this is painful.

One instinct to kill: "it's dynamic, so no CDN." That is wrong.

  • Modern CDNs do dynamic acceleration for content that cannot be cached at all.
  • Routing a request over the CDN's optimized backbone, with warm TLS connections held open between edge and origin, beats the open internet.
  • You skip the TLS handshake cost on every hop and ride better peering.

Here is the same hit-and-miss logic as a time-ordered view:

sequenceDiagram participant U as User participant E as Edge PoP participant O as Origin U->>E: GET logo png alt cached and fresh E-->>U: 200 from cache else miss or expired E->>O: fetch or revalidate O-->>E: 200 with body or 304 E-->>U: 200 response end
The fast path is one hop (user to edge). The slow path adds the edge-to-origin round trip, which is exactly the latency a miss pays and a hit avoids.

3A worked example: image serving for a 50M-user app#

Put real numbers on it, because this is the back-of-envelope an interviewer will push you toward.

The setup.

  • Product images for an e-commerce app.
  • 50 million daily active users, each session loading about 40 images.
  • Average image size 200KB after compression.
  • Origin is one region, us-west-2.

Request volume.

  • 50M users times 40 images is 2 billion image requests a day.
  • That is roughly 23,000 requests per second on average.
  • Peak around 70,000 RPS (a 3x peak-to-average factor is a safe number to say out loud).

Bytes.

  • 2 billion requests times 200KB is 400TB served per day.

Now the CDN math at a 97 percent hit rate, which is realistic for versioned image assets:

  • Origin requests: only 3 percent miss, so 70,000 peak RPS times 0.03 is about 2,100 RPS hitting origin. One modest fleet handles that. Without the CDN, origin eats all 70,000 RPS, a 33x difference in fleet size.
  • Origin bandwidth: 400TB times 0.03 is 12TB a day from origin, versus 400TB. The other 388TB serves from edges near users.
  • Latency: a hit from a nearby PoP returns in roughly 10 to 30ms. A miss pays the user-to-edge hop plus the edge-to-origin round trip, so a Sydney user on a miss might see 220ms. At a 97 percent hit rate, p50 and p90 sit in the hit range and the miss cost only shows up in the p99 tail. That tail is exactly why you care about hit rate, not just average.
~97%
The number that reshapes the whole designHit rate for versioned image assets. It turns 70,000 origin RPS into 2,100 and 400TB into 12TB, which is a 33x smaller fleet and a 25x bandwidth offload from a single config choice. Every trade-off below is really a fight to protect this number.

Cost sketch.

  • CDN egress runs on the order of 2 to 8 cents per GB depending on region and commit.
  • 388TB a day at 4 cents per GB is about 15,500 dollars a day, call it 465,000 dollars a month.
  • That is a real line item, and it is the number that justifies negotiating a committed-use discount.
  • Serving the same bytes straight from origin egress is usually more expensive per GB and forces a far larger origin fleet, so the CDN wins on both axes.

The point of the numbers is to show both wins are measurable: a 33x smaller origin fleet and a 25x bandwidth offload, from one config choice.

4Trade-offs#

This is where interviews are won or lost. A CDN is not free magic. Here is what you actually trade.

Freshness versus hit rate.

  • Long TTLs give high hit rates and low origin load, but users may see stale content after a change.
  • Short TTLs keep content fresh but push traffic to origin and slow users on misses.
  • The standard fix: content-hashed filenames (app.a9f3c1.js) with a one-year TTL, plus a short TTL on the HTML that references them.
  • The HTML changes, points at new hashed files, and you never purge anything. State that pattern out loud.

Consistency.

  • A CDN is an eventually consistent cache by nature.
  • Right after a purge, different PoPs may serve different versions for a few seconds to minutes.
  • For a marketing site, fine. For a config file that controls feature flags, dangerous.
  • Know which of your content can tolerate it.

Cost shape.

  • Pricing is mostly egress bandwidth plus request count.
  • For high-volume static content it is cheaper than serving from origin because of offload.
  • Egress at scale is a real line item (see the 465,000 dollars a month above).
  • Some providers charge extra for cache invalidations or for traffic in expensive regions like India or South America.
Pause before you read on: your hit rate is 60 percent and someone asks "is that good?" What do you check first?
Reveal the answer
You do not answer yes or no. You ask what the content is, then look at the cache key and the TTL. 60 percent on versioned static assets is broken: almost certainly the cache key includes something high-cardinality (a full cookie, a tracking query string) so near-identical requests keep missing, or the TTL is too short and everything revalidates. 60 percent on genuinely personalized responses might be as good as it gets. The number means nothing without the content behind it.

Here is how I weigh a few common choices:

Decision Option A Option B When to pick which
TTL length Long TTL + hashed names Short TTL + revalidate Long for versioned assets, short for frequently edited HTML or feeds
What to cache Static only Static + dynamic acceleration Add dynamic path when origin is far and latency matters more than caching
Invalidation Purge on deploy Versioned URLs, never purge Prefer versioned URLs; purge only when you cannot change the URL
Cache key Strict URL only Include headers or query Keep it minimal; add dimensions only when content genuinely varies
Fill strategy Pull on first request Push before launch Pull by default; push for a global launch where the first hit must be fast

Push versus pull.

The default
Pull
How it fills
First user triggers the fetch from origin.
First hit
Slow: it pays a cold cache miss.
Best when
Almost always. Simpler, no pre-staging.
Weakness
That first request per region is the slow one.
The exception
Push
How it fills
You pre-stage content to edges before launch.
First hit
Fast: it is already warm everywhere.
Best when
You cannot afford a slow first hit.
Use case
Global launch or a video premiere where the whole world requests one file in the same second.

The thundering herd.

  • On a popular cache miss, many edges or many users can hit origin at once.
  • Good CDNs collapse these into a single origin request (request coalescing).
  • Concrete case: a premiere drops and 500,000 viewers request segment 1 in the same 2 seconds against a cold edge.
  • Without coalescing the edge opens 500,000 origin fetches and origin falls over.
  • With it the edge sends 1 fetch and fans the one response out to all 500,000.
  • If you are designing a CDN yourself, you need this.

5Where it is used#

Reach for a CDN when any of these are true.

  • Static assets at scale. Images, CSS, JS, fonts. The bread and butter. A news site or e-commerce catalog serves the bulk of its bytes this way, as the worked example showed.
  • Video and large downloads. Streaming pushes nearly all its traffic through CDNs, often using segmented formats (HLS/DASH) where each 2-to-10-second chunk is a separate cacheable file. Game patches and OS updates work the same way: one 50GB file, millions of identical requests, perfect for edge caching.
  • Global APIs with cacheable responses. A product listing that changes a few times a day. Cache the GET at the edge with a 30-second TTL and you cut both latency and database load.
  • Absorbing attacks. The edge sits in front of origin, so CDNs double as a first line of defense against traffic floods and act as the home for a web application firewall. The edge soaks up junk before it reaches you.
  • TLS termination at the edge. Ending the encrypted connection near the user and keeping a warm link to origin shaves real milliseconds off every request, since the handshake happens over the 5ms edge hop, not the 200ms origin hop.

In a typical web system the CDN sits between the user and your load balancer. Static requests resolve entirely at the edge. Dynamic requests pass through to your origin.

flowchart LR A[Client] --> B[CDN Edge] B --> C[Load Balancer] C --> D[App Service] D --> E[(Database)] D --> F[(Cache)] B --> G[(Object Store)]
The edge is the front door for everything. Static requests dead-end at the edge and the object store. Only dynamic requests travel the full depth to the app service and database.

6Common pitfalls and gotchas#

I have debugged every one of these in production. They show up in interviews too.

Caching things you should not.

  • The classic disaster: an edge caches a page carrying a Set-Cookie with a session token, then serves that cookie to the next user. Now everyone is logged in as one person.
  • Anything personalized must either not be cached or must vary the cache key correctly.
  • When in doubt, mark user-specific responses Cache-Control: private, no-store.

Forgetting the cache key dimensions.

  • API returns different content by Accept-Language but the cache key ignores it: the first visitor's language gets served to everyone.
  • Key on something high-cardinality like a full cookie and your hit rate collapses toward zero, so the CDN becomes a slow pass-through that is worse than no CDN.

Treating invalidation as instant.

  • Purges take time to propagate across hundreds of PoPs, typically seconds to a few minutes, and some are eventually consistent.
  • Assume "I purged, so the old file is gone everywhere now" and you will ship bugs.
  • Design so you rarely need to purge. Versioned URLs make this a non-issue.

Cold cache after deploy or purge.

  • Right after a global purge your hit rate drops to zero and every request stampedes origin.
  • In the worked example that is a jump from 2,100 origin RPS to 70,000 in an instant, a 33x spike that can knock origin over.
  • Stagger purges, or use versioned URLs so old and new coexist.

Ignoring the first-byte penalty on misses.

  • A cache miss is slower than no CDN at all for that one request, because it adds the user-to-edge hop plus the edge-to-origin hop.
  • Your p99 includes these cold misses.
  • If someone says "a CDN made everything faster," ask them about the miss path.

Compression and range requests.

  • Serving uncompressed assets, or not supporting byte-range requests for video seeking, quietly wastes bandwidth and breaks playback resume.
  • Easy to forget, easy to check.
Red flag that fails you here

"We purge the CDN on every deploy" and a shrug when I ask what happens next. That one habit invites every bad outcome above: a cold-cache stampede on origin, inconsistent PoPs mid-propagation, and a hit rate that keeps resetting to zero. Reach for versioned, content-hashed URLs on your own and the whole class of problems disappears.

7How it shows up in interviews#

When I ask about CDNs I am probing whether you understand the two wins (latency and offload) and whether you know a cache has costs.

From the interviewer's chair

I am not after a definition. I am watching for whether you treat the CDN as a bolt-on or as something that reshapes the whole load profile. The candidate who connects "97 percent offload" to "origin fleet drops from 400 to 4" to "so my capacity estimate changes" is the one I remember.

What I listen for:

  • Do you distinguish static from dynamic, and know the CDN helps both for different reasons?
  • Can you reason about hit rate? If I say "our hit rate is 60 percent, is that good?" a strong candidate asks what the content is, checks the cache key, and checks whether TTLs are too short.
  • Do you handle invalidation sanely? "Versioned, content-hashed URLs with long TTL" is a green flag. "We purge on every deploy" invites follow-ups.
  • Do you name failure modes? Thundering herd on a miss, caching private data, stale config.
Shallow
Weak answer
Says
"We put a CDN in front to make it fast."
Problem
True but tells me nothing about when a CDN hurts, how correctness works, or what hit rate you expect.
My move
"What happens on a cache miss?" and watch it fall apart.
Staff-level
Strong answer
Static
Content-hashed names, one-year TTL, never purged, hit rate above 95 percent.
Numbers
2 billion requests a day means origin sees about 2,000 RPS instead of 70,000, so a small fleet is enough.
Dynamic
Product API GETs cached 30 seconds, keyed on path plus region header, cutting DB load about 80 percent.
Edges
Never cache authenticated responses; on a miss the edge coalesces so origin sees one fetch, not thousands.

That strong answer shows you understand the levers, the numbers, and the sharp edges. It is also honest: it says what is cached, what is not, and why.

Follow-ups the interviewer will ask (and your answers)
"What exactly happens on a cache miss, and why is it slower than no CDN?"
The edge has nothing fresh, so the request pays the user-to-edge hop plus a full edge-to-origin round trip, then the edge stores the copy and responds. That one request is slower than hitting origin directly, which is why misses live in your p99 tail. The win is that the next user in that region gets a hit, so you eat the cost once per region per TTL window, not per request.
"A video premiere drops and 500,000 people request segment 1 at once against a cold edge. What saves origin?"
Request coalescing. The edge recognizes concurrent requests for the same uncached key, sends exactly one fetch to origin, and fans that single response out to all 500,000 waiters. Without it the edge opens 500,000 origin fetches and origin falls over. For a known-hot launch I would also pre-push the file to edges so the first hit is already warm.
"How do you ship new content without stale copies lingering in cache?"
Content-hashed filenames with a one-year TTL, so a new build produces new URLs and I never purge the old ones. The HTML that references them gets a short TTL (say 60 seconds), so it flips to the new hashed files quickly. Old and new coexist, there is no purge propagation window, and no cold-cache stampede on origin.
"Our hit rate is 60 percent. Good or bad?"
Depends entirely on the content. For versioned static assets that is broken, and I would look at the cache key first (a full cookie or a tracking query string fragmenting near-identical requests) then the TTL. For genuinely personalized responses, 60 percent might be the ceiling. The number is meaningless without knowing what is behind the key.
"Can a CDN help content you cannot cache at all?"
Yes, through dynamic acceleration. Even for uncacheable responses, routing over the CDN's backbone with warm TLS connections held open between edge and origin beats the open internet. You terminate TLS at the nearby edge over a 5ms hop instead of the 200ms origin hop, and ride better peering on the way back. So "it's dynamic, no CDN" is the wrong instinct.

What you can now explain in the room

  • The two separate wins a CDN buys: lower user latency and lower origin load, and why both matter.
  • How a request flows through an edge, and the exact difference between the hit path and the miss path.
  • How to derive the numbers: 70,000 peak RPS, a 97 percent hit rate, and the 33x origin fleet reduction it buys.
  • Why versioned, content-hashed URLs with a long TTL beat purging on every deploy.
  • How cache keys become a correctness bug: serving one user's cookie, or collapsing your hit rate to zero.
  • Why a cache miss is slower than no CDN, and how request coalescing stops a cold-cache stampede.

Next, try the System Design Question walkthrough on designing a global photo or video sharing service, where CDN caching strategy is the center of the problem, not a footnote.

Get a prep plan built around your Content Delivery Networks (CDN) interview

Tell us the role and your interview date. We will send back a dated, day by day plan. Free.

Thanks. Check your inbox, your Content Delivery Networks (CDN) prep plan is on the way.