System Design Bible

Concept 5: Content Delivery Networks (CDNs)

System Design Bible — File 05 of 10 Difficulty: ★★★☆☆ Prerequisites: Files 01–02, plus the physics and DNS/HTTP-caching facts in Section 0.


Table of Contents#

  1. Prerequisites — What You Must Understand First
    • 0.1 Latency has a hard floor set by the speed of light
    • 0.2 A proxy, and "origin" vs "edge"
    • 0.3 DNS as a routing tool, not just a phone book
    • 0.4 Counting the round trips — the number a CDN actually attacks
    • 0.5 Bandwidth, latency and throughput are three different things
    • 0.6 TCP slow start and the congestion window — why long RTT throttles transfer
    • 0.7 Autonomous Systems, BGP, peering and transit — how the internet routes
    • 0.8 Anycast from first principles
  2. Architectural Definition & "The Why"
  3. The Recursive Sub-Concept Tree
    • 2.1 Origin Server · 2.2 Edge Server / PoP · 2.3 Push vs Pull · 2.4 Hit ratio & cache hierarchy · 2.5 TTL & Cache-Control · 2.6 Anycast
    • 2.7 The Cache Key · 2.8 Query strings · 2.9 Cookies · 2.10 Vary at the edge · 2.11 Request collapsing · 2.12 Cache-status headers & Age · 2.13 Surrogate keys · 2.14 IXPs, peering and embedded caches · 2.15 The private backbone
  4. Deep-Dive Mechanics: How a CDN Serves a Request
  5. Anycast & Request Routing — How Users Find the Nearest Edge
  6. Cache Control, Invalidation & Dynamic Content
  7. Edge Protocol Optimizations — TLS, HTTP/2, QUIC, Compression
  8. Dynamic Content Acceleration — Why a CDN Helps Even When Nothing Is Cacheable
  9. Video & Large-File Delivery
  10. Edge Compute
  11. Security at the Edge
  12. Measuring a CDN
  13. Pros, Cons & Trade-offs
  14. Interview Diagnostic Framework (Symptom → Solution)
  15. Real Implementations & Product Landscape
  16. Real-World Engineering Scenarios
  17. Interview Gotchas & Failure Modes
  18. Whiteboard Cheat Sheet

0Prerequisites — What You Must Understand First#

A CDN is "caching (File 02) + geography." The "geography" part rests on one piece of physics and one piece of internet plumbing.

This section is long, and deliberately so. Almost every wrong answer about CDNs in an interview traces back to a missing prerequisite: the candidate does not actually know how many round trips a page load costs, does not know why a fat pipe with a long delay still transfers slowly, does not know what DNS does between "user types a name" and "browser opens a socket," and does not know what BGP is even though anycast — the thing they are about to name-drop — is made of BGP. We will fix all of that before the word "CDN" does any real work.

0.1Latency has a hard floor set by the speed of light#

You cannot make distant things fast, and understanding why is the entire justification for CDNs. Data travels through fiber-optic cable at roughly two-thirds the speed of light — fast, but finite. A signal from Sydney to a server in Virginia crosses ~16,000 km each way; even at light-ish speed, the round trip takes ~160–200 milliseconds, and no faster CPU, bigger server, or better code can reduce it — it's bounded by distance and physics. Worse, loading a web page isn't one round trip: it's a DNS lookup, then a TCP handshake, then a TLS handshake, then the HTML, then dozens of follow-up fetches for CSS/JS/images — each potentially its own round trip. Stack dozens of 200 ms round trips and you get seconds of load time for a faraway user, while a nearby user gets the same page in a fraction of a second. The inescapable conclusion: the only way to cut distance-latency is to cut the distance — physically place a copy of the content near the user. That is what a CDN does, and it's why "add a faster server" can never substitute for it. Keep this floor in mind: latency between continents is a law of physics, not an engineering shortcoming.

0.1.1 Do the arithmetic yourself — the numbers you should be able to produce on a whiteboard#

Assertions are not understanding. Derive the floor from constants, because an interviewer will ask "how do you know Tokyo can't be fast from Virginia?" and the answer is four lines of arithmetic.

**Constant 1 — the speed of light in vacuum, c, is 299,792,458 m/s, which you round to 300,000 km/s**. Nothing carrying information travels faster; this is not an engineering limit that a better vendor beats, it is a property of spacetime.

Constant 2 — light in glass is slower. Optical fibre is made of silica glass with a refractive index of about 1.47. Refractive index n is defined as the ratio of light's speed in vacuum to its speed in that medium, so the propagation speed inside the fibre is c / n = 300,000 / 1.47 ≈ 204,000 km/s. Engineers round this to ~200,000 km/s, or equivalently **"two-thirds of c," or "5 microseconds per kilometre," or "1 millisecond per 200 km."** Memorize the last form; it lets you do these estimates in your head.

Constant 3 — cable does not run in straight lines. The great-circle distance (the shortest path over the surface of the sphere) from New York to London is about 5,585 km. The actual submarine cable route is longer — cables follow ocean-floor topography, avoid trenches and fishing grounds, and land at specific cable stations — so a realistic fibre path is 6,500–7,000 km. A useful rule of thumb: real fibre distance ≈ 1.2–1.5× great-circle distance.

Now the computation, twice: once for the theoretical floor, once for reality.

ASCII diagram
NEW YORK  ->  LONDON

(a) Theoretical floor, great-circle distance, speed of light in glass
      one way   = 5,585 km / 200,000 km/s   = 0.0279 s  = 27.9 ms
      round trip= 2 x 27.9                  = 55.8 ms      <-- HARD FLOOR

(b) Realistic, actual cable path
      one way   = 6,800 km / 200,000 km/s   = 34.0 ms
      round trip= 68.0 ms  of pure propagation
      plus per-hop equipment delay: ~12 routers x ~0.5 ms  = ~6 ms
      plus queuing/serialization                            = ~2-6 ms
      OBSERVED RTT                                          = ~70-80 ms

Measured reality agrees: ping between a New York datacenter and a London datacenter reliably reports 70–80 ms round-trip time. The floor is 56 ms and you observe 75 ms, so the "overhead" the industry can still optimize is about 19 ms — roughly a quarter of the total. Three-quarters of that latency is the speed of light and cannot be optimized by anyone, ever, for any amount of money.

Sub-Concept: RTT (Round-Trip Time). RTT is the elapsed time from the moment a machine puts the first bit of a message on the wire to the moment it receives the first bit of the reply. It is the single most important number in networked-system design because virtually every protocol is a conversation, and a conversation costs RTTs. It is not the same as "latency" loosely used: one-way latency is half of RTT only when the path is symmetric, which on the internet it frequently is not (traffic to you and traffic from you can take different routes with different lengths, a condition called path asymmetry). You measure RTT with ping (which sends an ICMP echo request and times the echo reply) or, more usefully for real traffic, with curl -w '%{time_connect}\n' -o /dev/null -s https://example.com, which reports how long the TCP connection took to establish — one RTT. Why it matters here: every optimization in this entire file is, ultimately, either "reduce the RTT" (move the server closer) or "reduce the number of RTTs" (change the protocol). Those are the only two moves available.

Run the same arithmetic for the other pairs you will be asked about, and commit the table to memory:

PathGreat-circleFloor RTT (fibre)Typical observed RTT
Same city (client → local PoP)5–50 km~0.5 ms1–10 ms (last-mile access dominates)
Same metro region~100 km~1 ms5–15 ms
New York → Chicago1,150 km~11.5 ms20–25 ms
New York → London5,585 km~56 ms70–80 ms
London → Singapore10,850 km~109 ms150–180 ms
Sydney → Virginia (US)15,900 km~159 ms200–230 ms
Anywhere → geostationary satellite → anywhere71,600 km (up+down twice)~477 ms in vacuum600+ ms

The satellite row is included because it is the cleanest proof that the physics is real: geostationary orbit is 35,786 km up, the signal travels through near-vacuum at full c rather than through glass at 0.68c, and it is still catastrophically slow, purely because the distance is enormous. No compression algorithm, no faster modem, and no better code changes that. (This is precisely why Starlink and other LEO — Low Earth Orbit — constellations exist: by flying at 550 km instead of 35,786 km they cut the propagation distance by 65×, trading a hard latency problem for a hard "you need thousands of satellites and constant handoffs" problem.)

Why "the last mile" is the other half of the story. Notice the first row of the table: a client in the same city as a PoP still typically sees 1–10 ms, far above the 0.5 ms propagation floor. That gap is the last mile — the access network between the user's device and their ISP's first router. Wi-Fi adds 1–3 ms and retransmits on interference; DOCSIS cable modems add 5–15 ms of scheduling delay because upstream transmission slots are granted by the head-end rather than taken freely; 4G LTE adds 30–50 ms of radio-scheduling and control-plane latency; 5G targets 10–20 ms. The practical consequence for CDN design is important and often missed: once the edge is inside the user's metro area, further reductions in distance buy almost nothing, because access-network latency now dominates. This is why CDNs stop at a few hundred to a few thousand PoPs rather than building one per neighbourhood — the returns flatten. It is also the argument for putting caches inside the ISP (§2.14, and Netflix Open Connect in §15.1), which attacks the last mile itself rather than the backbone.

0.1.2 The business case, in real published numbers#

Rule 6 says tie everything to a real limit. The physical limit is above; the economic limit that got CDNs funded is this. Amazon's oft-cited internal experiment found every 100 ms of added latency cost about 1% of sales. Google found that deliberately increasing search-results latency by 400 ms reduced searches per user by 0.6%, and that the effect persisted for weeks after the latency was removed. Akamai's 2017 study found a 100 ms delay reduced conversion rates by 7%, and that 53% of mobile visitors abandon a page taking over 3 seconds. Google's Core Web Vitals — the performance metrics that feed search ranking — set a "good" threshold of 2.5 seconds for Largest Contentful Paint (LCP), the time until the biggest visible element on screen has rendered. If a Sydney user's baseline RTT to your Virginia origin is 220 ms and a page load costs even 8 sequential round trips, you have burned 1.76 seconds before a single byte of image data moves. You cannot hit a 2.5 s LCP budget from the other side of the planet. That is the whole business case in one sentence.

Hold this: latency is 5 µs per kilometre of fibre, ~75 ms New York↔London, ~220 ms Sydney↔Virginia, three-quarters of it unfixable physics; and a few hundred milliseconds is worth a measurable percentage of revenue.

0.2A proxy, and "origin" vs "edge"#

A proxy server is a machine that sits between a client and a destination server, forwarding requests and responses on their behalf. A caching proxy additionally keeps a copy of responses it has seen, so it can answer future identical requests itself without contacting the destination. A CDN is a globally-distributed fleet of caching proxies. Two terms recur constantly: the origin is your authoritative server (or storage bucket) that holds the real, canonical content — the source of truth. An edge server (or PoP, Point of Presence) is one of the CDN's caching proxies, positioned in a data center physically near end users. The whole game is: users talk to the nearby edge (fast); the edge only occasionally talks to the faraway origin (slow, but rare). If "cache hit," "cache miss," and "TTL" from File 02 aren't crisp, re-read File 02 §2 — a CDN is those exact concepts spread across the planet.

Forward proxy vs reverse proxy — the distinction that trips people up. The word "proxy" covers two mirror-image deployments and CDNs are firmly one of them. A forward proxy sits in front of clients and is deployed on behalf of the clients: a corporate web proxy that all employee browsers are configured to use, a VPN egress node, an ad-blocking proxy. The clients know about it (they are configured to use it) and the destination servers do not (they just see traffic from the proxy's IP). A reverse proxy sits in front of servers and is deployed on behalf of the server operator: the clients do not know it exists (they think they are talking to example.com and they are, as far as they can tell), and the real servers behind it are hidden. A CDN edge server is a reverse proxy — you, the site owner, put it there; your users never configured anything; and it impersonates your origin so completely that the browser's address bar, its TLS certificate check, and its cookies all behave as if it were your origin. Everything File 01 taught about reverse proxies — TLS termination, connection pooling, health checks, header rewriting — applies verbatim to a CDN edge, because a CDN edge is a reverse proxy that additionally caches and happens to have 300 siblings around the world.

The exact terms, because they are used loosely and you should not be loose with them:

The economics in one line, which is the entire reason the architecture is shaped this way: the user↔edge hop is short, cheap, and traversed billions of times; the edge↔origin hop is long, expensive, and — if you have done your job — traversed rarely. Every design decision in this file is an attempt to move traffic from the second category into the first.

0.3DNS as a routing tool, not just a phone book#

From File 01 §0.4 you know DNS translates a name (example.com) into an IP address. The extra idea you need for CDNs: **DNS can return different answers to different users.** When a user's device asks "what's the IP for cdn.example.com?", the CDN's DNS can look at where the asker is and reply with the IP of the nearest edge server — so users in Tokyo and users in London, asking the identical question, get different IPs pointing to different nearby PoPs. This "answer depends on who's asking and where they are" is one of the two mechanisms (the other being anycast, covered in §4) that steer each user to their closest edge. So DNS here is not merely a static lookup — it's an active, location-aware routing layer. This reframing is essential before Section 4.

0.3.1 DNS resolution in full — every actor, every record, every cache#

You cannot reason about GeoDNS, TTL-bounded failover, or EDNS Client Subnet until you can narrate a resolution end to end. Here it is with real names and real timings.

The actors.

  1. The stub resolver. A small library inside your operating system (on Linux, glibc's resolver or systemd-resolved; on macOS, mDNSResponder; on Windows, the DNS Client service). It knows almost nothing — it just forwards the question to a configured recursive resolver and caches the answer briefly. Your browser also keeps its own small DNS cache in front of this (Chrome's is visible at chrome://net-internals/#dns), which is why a DNS change sometimes appears to take effect in one application and not another.
  2. The recursive resolver (a.k.a. recursive nameserver, or just "the resolver"). The machine that does the actual work of walking the DNS hierarchy on your behalf. It is usually run by your ISP, or it is a public resolver you chose: **Google Public DNS at 8.8.8.8, Cloudflare at 1.1.1.1, Quad9 at 9.9.9.9, or OpenDNS at 208.67.222.222. It maintains a large cache shared across all of its users. This machine's location, not yours, is what a GeoDNS system sees** — hold that thought, it is the single biggest weakness of DNS-based routing (§4.3).
  3. The root servers. Thirteen logical root nameservers named a.root-servers.net through m.root-servers.net, which are actually over 1,900 physical machines worldwide because each logical server is itself anycast (§0.8). They know one thing: which nameservers are authoritative for each top-level domain (.com, .org, .io, .uk).
  4. The TLD (Top-Level Domain) servers. For .com, these are Verisign's a.gtld-servers.net and friends. They know which nameservers are authoritative for each second-level domain under them (example.com).
  5. The authoritative nameserver. The machine that holds the actual, final answer for example.com — the zone file with all its records. If you use a CDN, this is very often the CDN's own nameserver, because owning the authoritative DNS is how a CDN gets to give different answers to different askers.

The walk, with a stopwatch. Your laptop in Sydney wants www.example.com and nothing is cached anywhere:

ASCII diagram
 stub ---(1)--> recursive resolver (ISP, 10 ms away)
                    resolver ---(2)--> ROOT server: "who serves .com?"        [~20 ms]
                              <------  "ask a.gtld-servers.net (192.5.6.30)"
                    resolver ---(3)--> .com TLD server: "who serves example.com?" [~40 ms]
                              <------  "ask ns1.example-cdn.net (203.0.113.9)"
                    resolver ---(4)--> authoritative NS: "A record for www.example.com?" [~30 ms]
                              <------  "www.example.com. 60 IN A 198.51.100.42"
 stub <---(5)--- resolver returns 198.51.100.42, and caches it for 60 s
                                                  TOTAL COLD RESOLUTION: ~110 ms

**That is 110 milliseconds before your browser has even begun to open a TCP connection.** On a warm cache — which is the common case, because the resolver serves thousands of users and someone asked recently — steps 2 through 4 vanish and the whole thing costs one 10 ms round trip to the resolver. The variance between 10 ms and 110 ms for the identical operation is why DNS optimization (short chains, few CNAMEs, prefetching) is a real discipline.

The record types you must know by name.

**Sub-Concept: TTL in DNS, and why it is a commitment, not a hint. Every DNS record carries a TTL (Time To Live)** in seconds. It instructs every cache along the path — the recursive resolver, the OS stub, the browser — how long it may reuse this answer without asking again. A 198.51.100.42 with TTL 60 means "you may use this for 60 seconds." The crucial and under-appreciated property: once you have handed out a record with TTL 3600, you have no way to take it back. There is no purge, no invalidation, no callback. Somewhere in the world a resolver will use that answer for the next hour, and a meaningful minority of resolvers and client libraries ignore TTLs entirely and cache for their own convenience (Java's JVM historically cached DNS forever by default via the networkaddress.cache.ttl security property; many mobile apps and connection pools resolve once at startup and never again). Consequences you must be able to state: (1) DNS-based failover is bounded below by your TTL and in practice is worse than your TTL; a 60 s TTL means "most users move within 60 s, some within 10 minutes, a few never until they restart." (2) Short TTLs cost you: every expiry forces a fresh resolution, adding a round trip and load on your authoritative servers; a 30 s TTL on a site with 10 million daily users generates a lot of DNS queries, and you pay per query on managed DNS (Route 53 charges roughly $0.40 per million standard queries, and about $0.60–$0.70 per million for latency-based or geolocation routing). (3) The migration playbook is therefore always: **lower the TTL to 60 s a day or two before the change, make the change, wait, then raise the TTL back.** Forgetting the "before" is how you turn a five-minute cutover into a two-hour one.

How to actually look at this. dig www.example.com A +noall +answer prints the answer section with TTLs. dig +trace www.example.com performs the entire root→TLD→authoritative walk in front of you, printing each delegation — run it once and the diagram above stops being abstract. dig @1.1.1.1 www.example.com asks a specific resolver, which is how you compare what different resolvers are being told (and thus observe GeoDNS in action). dig CHAOS TXT id.server @1.1.1.1 asks an anycast server to name itself, revealing which PoP you actually reached.

Hold this: DNS is a hierarchy of caches with commitments called TTLs, CNAMEs are how a CDN takes control of a hostname, the answer depends on which resolver asks, and you can never un-hand-out a record.

0.4Counting the round trips — the number a CDN actually attacks#

Everything above establishes that one round trip is expensive. The reason CDNs are transformative rather than merely nice is that **a web page load is not one round trip — it is a long, mostly sequential chain of them**, and each link in the chain is multiplied by the RTT. Count them explicitly, because this count is the thing a CDN attacks from two directions at once (make RTT smaller, and make the count smaller).

Take a user in Sydney loading https://shop.example.com/ served directly from an origin in Virginia. RTT = 220 ms. Nothing is cached anywhere. Here is the complete ledger:

ASCII diagram
STEP                                        RTTs   ELAPSED (at 220 ms/RTT, DNS to a nearer resolver)
------------------------------------------  -----  ---------------------------------------------
1. DNS: stub -> recursive resolver             1    ~10 ms  (resolver is local)
2. DNS: resolver -> root -> TLD -> auth        3    ~110 ms cold (0 ms if warm)
3. TCP handshake: SYN -> SYN/ACK -> ACK        1    +220 ms   = 330 ms
4. TLS 1.2 handshake (2 RTTs)                  2    +440 ms   = 770 ms
   (TLS 1.3 needs only 1 RTT               ->  1    +220 ms   = 550 ms)
5. HTTP GET / -> first byte of HTML            1    +220 ms   = 990 ms   <-- TTFB
6. HTML parsed; browser discovers CSS + JS
   New connection to a second hostname?
     -> repeat DNS + TCP + TLS               4-7    +880-1540 ms
7. GET /app.css, GET /app.js                   1    +220 ms
8. CSS parsed; discovers webfont + images      1    +220 ms
9. Fonts and hero image fetched                1    +220 ms
------------------------------------------  -----  ---------------------------------------------
TOTAL (single origin, TLS 1.3, warm DNS)    ~9-11 RTTs   ~2.0-2.4 SECONDS before the page is usable

Now change exactly one thing — put a CDN edge in Sydney, 8 ms away — and re-run the same ledger. Steps 3, 4, 5, 7, 8 and 9 all now cost 8 ms instead of 220 ms. The only step that still costs a long trip is the first origin fill for the HTML, and only on a cache miss, and only for the first user:

ASCII diagram
TOTAL (CDN edge 8 ms away, everything cached)   ~9 RTTs x 8 ms  ~=  75-120 ms

Two-and-a-half seconds becomes a tenth of a second, with not one line of application code changed. That number — roughly a 20× improvement in wall-clock page load for a distant user — is why CDNs are not an optimization you get to defer.

Now notice the second lever. The count itself (9–11) is attackable, and modern edges attack every item on the list:

Hold this: **a page load costs 9–11 sequential round trips; a CDN multiplies every one of them by a 10× smaller RTT and removes several of them outright. The product of those two effects is the whole value proposition.**

0.5Bandwidth, latency and throughput are three different things#

These three words are used interchangeably in casual speech and they mean completely different things. Conflating them produces the single most common wrong intuition in system design: "our users have gigabit fibre, so file size doesn't matter." It matters enormously, and here is why.

Latency is delay — how long one bit takes to get from A to B, measured in milliseconds. It is set by distance and by per-hop processing (§0.1). Think of it as the length of the pipe.

Bandwidth is capacity — how many bits per second the link can carry, measured in Mbps or Gbps. It is set by the physical medium and the equipment. Think of it as the width of the pipe.

Throughput (also called goodput when you count only useful application bytes and exclude protocol headers and retransmissions) is what you actually achieve — the real bits per second your transfer sustains. It is bounded above by bandwidth, but it is very often far below it, and the thing dragging it down is usually latency. Think of it as the water actually flowing.

The analogy that makes this stick: a truck full of hard drives driving from Los Angeles to New York has colossal bandwidth (a truck holds petabytes; divided by 40 hours that is hundreds of Gbps) and appalling latency (40 hours for the first bit). AWS literally sells this — the Snowball and Snowmobile appliances — because for a 100 PB migration, driving is genuinely faster than any network you can afford. Conversely, a stock-trading microwave link between Chicago and New York has pitiful bandwidth (a few hundred Mbps) and superb latency (microwaves travel through air at ~0.99c and take a straighter path than fibre, so ~4 ms one way versus fibre's ~6.5 ms), and firms have spent hundreds of millions of dollars for those 2.5 milliseconds. Bandwidth is bought; latency is bounded by physics.

Sub-Concept: the Bandwidth-Delay Product (BDP) — the number that explains everything. The BDP is bandwidth × round-trip time, and it has units of bytes. Physically it is the amount of data that is "in flight" on the wire at any instant — data the sender has transmitted but that the receiver has not yet acknowledged. It is the volume of the pipe: length (RTT) × width (bandwidth).

Work it: a 100 Mbps link with a 200 ms RTT has BDP = 100,000,000 bits/s × 0.2 s = 20,000,000 bits = 2.5 MB. To keep that link fully busy, the sender must be allowed to have 2.5 MB of unacknowledged data outstanding at all times. If it may only have 64 KB outstanding, then it sends 64 KB, stops, and waits 200 ms for the acknowledgement — achieving 65,536 bytes / 0.2 s = 327 KB/s ≈ 2.6 Mbps on a 100 Mbps link. You are using 2.6% of the bandwidth you paid for, and the cause is entirely the delay.

This is not hypothetical: the original TCP receive-window field is 16 bits, capping the advertised window at 65,535 bytes, which is exactly the 64 KB in the calculation above. The fix is TCP Window Scaling (RFC 7323), a TCP option negotiated in the SYN packets that specifies a left-shift factor (0–14) applied to the window field, raising the maximum window to 1 GB. It is on by default on every modern OS (net.ipv4.tcp_window_scaling = 1 on Linux) — but middleboxes, old firewalls, and misconfigured appliances still occasionally strip the option, and the symptom is exactly this: a fast link that inexplicably transfers at a few megabits over long distances. This condition — a high-bandwidth, high-latency path that TCP cannot fill — has a name: a "long fat network," or LFN, pronounced "elephant."

The CDN tie-back, which is the punchline of this whole sub-section: shortening the RTT from 200 ms to 10 ms shrinks the BDP from 2.5 MB to 125 KB. Suddenly the window sizes, buffers, and congestion-control behaviour that were catastrophically inadequate for the long path are more than sufficient for the short one. A CDN does not just reduce the delay; it reduces the delay to the point where TCP starts working properly at all. That mechanism — not caching — is why a CDN accelerates even a completely uncacheable response (§7).

Hold this: latency is pipe length, bandwidth is pipe width, throughput is actual flow, and their product (BDP) is how much data must be in flight to keep the pipe full. Long RTT means enormous BDP means TCP struggles.

0.6TCP slow start and the congestion window — why long RTT throttles transfer#

The BDP above says how much data must be in flight. This section explains why TCP, left to itself, refuses to put that much in flight for a long time. This is the mechanism that makes edge termination (§3.3, §7) such a large win, and it is the prerequisite that candidates almost never have.

Why congestion control exists at all. In October 1986, the link between Lawrence Berkeley Laboratory and UC Berkeley — 400 yards apart — collapsed from 32 kbps to 40 bps, a factor of 1,000. The cause, diagnosed by Van Jacobson, was congestion collapse: senders transmitting faster than the bottleneck router could forward, the router's queue overflowing, packets dropping, senders retransmitting the lost packets on top of their existing send rate, and the whole system spiralling into a state where nearly all transmitted bytes were retransmissions of already-retransmitted data. The fix, shipped in 4.3BSD in 1988 and now in every TCP stack on earth, was to give each sender a self-imposed speed limit that starts small and probes upward until the network pushes back. That limit is the congestion window.

**Sub-Concept: cwnd — the congestion window. The congestion window (cwnd)** is a variable held by the sender stating the maximum number of unacknowledged bytes it will allow itself to have in flight. It is entirely the sender's own invention — no packet on the wire ever contains it, and the receiver never sees it. It exists alongside a second, different limit: **rwnd, the receive window**, which is advertised on the wire (it is the 16-bit window field of §0.5) and states how much buffer space the receiver has free. **The sender may have min(cwnd, rwnd) bytes outstanding.** rwnd protects the receiver from being overrun (that is flow control); cwnd protects the network from being overrun (that is congestion control). Confusing the two is a classic interview stumble; keep them straight by remembering **rwnd is about the endpoint's memory, cwnd is about the path's capacity.**

cwnd is measured in bytes but is universally discussed in units of MSS (Maximum Segment Size) — the largest chunk of application data one TCP segment carries, which on a standard 1500-byte-MTU Ethernet path is 1460 bytes (1500 minus 20 bytes of IP header minus 20 bytes of TCP header; see File 01 §0.5). So "cwnd = 10" means ten segments, about 14,600 bytes, and that number is about to matter a great deal.

Slow start, step by step, with real numbers. When a TCP connection opens, the sender has no idea what the path can carry, so it starts conservatively and doubles every round trip:

  1. **cwnd begins at the initial window (IW). RFC 6928 (2013) raised the standard initial window to 10 segments ≈ 14.6 KB**; before that it was 3 segments (~4.4 KB), and before that 1–2 segments. Modern Linux uses IW10 by default (ip route change ... initcwnd 10), and some CDNs deliberately raise it further on paths they trust.
  2. **The sender transmits cwnd bytes and stops**, waiting for acknowledgements.
  3. **For each acknowledgement received, cwnd grows by 1 MSS.** Since a full window's worth of acknowledgements arrives per RTT, and there were cwnd segments in that window, **cwnd doubles every RTT.** ("Slow start" is a spectacular misnomer — the growth is exponential. It is called "slow" only relative to the previous behaviour of blasting a full receive window immediately.)
  4. Growth continues until one of three things happens: cwnd reaches rwnd (the receiver is the limit); cwnd reaches ssthresh, the slow-start threshold, at which point the algorithm switches from exponential growth to the linear congestion avoidance phase (+1 MSS per RTT instead of doubling); or a packet is lost, which TCP interprets as the network's only signal that it is full.

Now the table that makes the point. How long does it take to transfer a 1 MB file, purely as a function of RTT, given slow start from IW10? Assume no loss and an unlimited receiver window, and count only the transfer (not the handshake):

ASCII diagram
 RTT #   cwnd (segments)   bytes this RTT     cumulative
   1           10             14.6 KB            14.6 KB
   2           20             29.2 KB            43.8 KB
   3           40             58.4 KB           102.2 KB
   4           80            116.8 KB           219.0 KB
   5          160            233.6 KB           452.6 KB
   6          320            467.2 KB           919.8 KB
   7          640            934.4 KB         1,854.2 KB   <-- 1 MB done during RTT 7

Seven round trips to move one megabyte, regardless of how much bandwidth you have. Now price those round trips:

PathRTTTime to transfer 1 MB (slow start, no loss)Effective throughput
User → edge in same metro10 ms7 × 10 ms = 70 ms~117 Mbps
User (Sydney) → origin (Virginia)220 ms7 × 220 ms = 1,540 ms~5.3 Mbps

Both users may have identical gigabit connections. The distant one gets 5 Mbps and the nearby one gets 117 Mbps, and the only difference is RTT. This is the concrete, mechanical answer to "why does a CDN help so much?" — not merely "it's closer," but "TCP's ramp is measured in round trips, so a shorter round trip makes the ramp itself 22× faster." Say that sentence in an interview and you will be visibly ahead of the candidate who says "it caches stuff nearby."

Loss makes it dramatically worse, and distance causes loss. When a packet is lost, the sender's reaction depends on the congestion-control algorithm:

The cross-layer consequence, which is the real prerequisite payoff. Because loss probability compounds per hop and per kilometre, a long path is not merely slower — it is lossier, and TCP punishes loss in units of RTT. So the penalties multiply: more RTTs to ramp, longer RTTs, more loss events, and more expensive recovery per loss. **Terminating the TCP connection at an edge 10 ms away splits one long, lossy, slow-ramping connection into two short ones — a 10 ms user↔edge connection that ramps in milliseconds, and a long-lived, already-fully-ramped, permanently-warm edge↔origin connection whose cwnd is large because it has been open for hours.** That single sentence is the mechanism behind §7's claim that a CDN accelerates even uncacheable content.

Hold this: TCP starts at ~14.6 KB and doubles per round trip, so transfer time is measured in RTTs, not in bandwidth; a 22× longer RTT is a 22× slower ramp; and splitting the connection at the edge lets both halves run at their best.

0.7Autonomous Systems, BGP, peering and transit — how the internet actually routes#

Section 4 will claim that "BGP delivers the packet to the nearest PoP." That sentence is meaningless without knowing what BGP is, what "nearest" means to it, and why it frequently disagrees with geography. This is also the prerequisite that connects to File 01 §2.2's Virtual IP (VIP) concept — an anycast address is precisely a VIP whose "cluster" is the entire planet.

The internet is not a network. It is ~75,000 networks that agreed to exchange traffic.

Sub-Concept: the Autonomous System (AS) and the ASN. An Autonomous System is a collection of IP prefixes under a single, coherent routing policy operated by one organization. Comcast is an AS. Deutsche Telekom is an AS. Google is an AS (several, in fact). Your university might be one. Each is identified by an ASN (Autonomous System Number), originally a 16-bit integer (0–65535) and since 2007 a 32-bit one, allocated by the regional internet registries (ARIN, RIPE NCC, APNIC, LACNIC, AFRINIC). You should recognize a few on sight because they appear in traceroutes and looking-glass output constantly: AS13335 is Cloudflare, AS15169 is Google, AS16509 is Amazon, AS32934 is Meta/Facebook, AS2906 is Netflix, AS20940 is Akamai's main network, AS7018 is AT&T, AS3356 is Lumen/Level 3 — historically the largest transit network in the world. Why it exists: routing every individual IP address globally is impossible (there are 4.3 billion IPv4 addresses); routing to ~75,000 policy domains that each aggregate large address blocks is tractable. The AS is the unit of internet routing, and BGP's entire job is to compute paths between ASes.

Sub-Concept: BGP (Border Gateway Protocol) — what it is and, crucially, what it is not. BGP (currently BGP-4, RFC 4271) is the protocol by which autonomous systems announce to each other which IP prefixes they can reach and by what path. Two routers in different ASes establish a long-lived TCP connection on port 179 — note that: the protocol that runs the internet runs over TCP like any other application — and exchange UPDATE messages. An UPDATE says, in effect: *"I can reach the prefix 198.51.100.0/24, and the path to get there traverses these autonomous systems in this order: AS64500 AS13335."* That ordered list is the AS_PATH attribute, and it is the heart of BGP.

Where it sits: BGP is an exterior gateway protocol — it routes between organizations. Inside a single organization, a different family of protocols (OSPF, IS-IS) computes routes within the network; those are interior gateway protocols and they genuinely optimize for a cost metric that usually correlates with link speed and latency. Do not confuse the two: your packets are steered by IS-IS inside an ISP and by BGP between ISPs.

**The critical property, stated precisely: BGP is a path-vector policy protocol, not a shortest-path protocol, and it has no concept of latency, bandwidth, congestion, or geography whatsoever.** There is no field in a BGP message for "this path is 40 ms." A router choosing among several announcements of the same prefix runs a fixed decision process, and the order of the tie-breakers tells you everything about why internet routing is sometimes bizarre:

1. **Highest LOCAL_PREF** — a purely local, purely commercial number the network operator sets by hand. Its universal use is: prefer routes learned from customers (who pay me) over routes learned from peers (free) over routes learned from transit providers (whom I pay). Money outranks every technical consideration, and it does so at step one. 2. **Shortest AS_PATH** — fewest autonomous systems traversed. Note this counts organizations, not routers, not kilometres, not milliseconds. A path across one enormous global AS counts as "1" even if it physically circles the planet; a path through three small, adjacent, city-local ASes counts as "3." 3. **Lowest ORIGIN type, then lowest MED (Multi-Exit Discriminator) — a hint from a neighbour about which of several links into their network to prefer. 4. Prefer eBGP-learned over iBGP-learned, then lowest interior cost to the exit point (this is the famous hot-potato routing**: hand the traffic off to the neighbouring network at the geographically nearest exit, so it spends the least time on your backbone and the most on theirs). 5. Lowest router ID — an arbitrary deterministic tiebreak.

What breaks, and how you diagnose it. Because step 1 is commercial and step 2 counts organizations rather than distance, BGP routinely produces paths that are geographically absurd. Traffic between two ISPs in the same African or South American city has historically been routed via Europe or Miami, adding 200+ ms, because neither ISP peered locally and both bought transit from a provider whose nearest exchange point was on another continent — a phenomenon known as tromboning or trombone routing. You diagnose it with traceroute (which reveals the hop-by-hop path and, via reverse-DNS names that usually encode airport codes — ae-1.r02.lond03.uk.bb.example.net is London — the physical geography), with mtr (a continuous traceroute showing per-hop loss and latency), or with a looking glass — a public web interface on someone else's router that runs show ip bgp <prefix> and prints the actual AS_PATHs that router is considering.

The other thing that breaks: BGP has essentially no built-in security. A router accepts an announcement largely because a neighbour said it. When a network announces a prefix it does not own — by accident or maliciously — that is a BGP hijack, and traffic for those addresses flows to the wrong place globally within minutes. Famous incidents: Pakistan Telecom took YouTube offline worldwide in 2008 by announcing YouTube's prefix internally to censor it and leaking the announcement to its transit provider; in April 2018 attackers hijacked Amazon's Route 53 DNS prefixes and used the resulting DNS control to steal roughly $150,000 of cryptocurrency from MyEtherWallet users. The mitigations are RPKI (Resource Public Key Infrastructure), a cryptographic database in which address holders publish signed ROAs (Route Origin Authorizations) stating "only AS13335 may originate this prefix," and route filtering by transit providers who check announcements against RPKI and the IRR (Internet Routing Registry) databases. Why a CDN customer should care: your CDN's ability to keep serving you depends on nobody successfully hijacking its anycast prefixes, and mature providers publish their RPKI posture. It is a fair and impressive question to ask a vendor.

Sub-Concept: transit, peering, and why "free" traffic exchange determines CDN placement. Two ASes can have exactly two kinds of commercial relationship, and the difference drives the entire economics of edge placement.

Transit is buying internet access. A smaller network pays a larger one to carry its traffic to everywhere — the transit provider announces the customer's prefixes to the whole internet and accepts traffic destined for it. Pricing is per Mbps of the 95th-percentile of measured throughput (samples every 5 minutes over a month, discard the top 5% of samples, bill on the highest remaining — a convention that deliberately forgives short spikes). Prices have collapsed over two decades from $1,200/Mbps/month in 1998 to roughly $0.10–$0.30/Mbps/month in major markets today, and are still 5–20× higher in poorly-connected regions, which is exactly where CDNs deliver the biggest wins.

Peering is swapping traffic. Two networks connect directly and exchange traffic destined for each other's customers at no charge to either party (this is settlement-free peering). Each saves the transit fee it would otherwise pay to reach the other, and both get a shorter, lower-latency, more controllable path. Peering happens either privately — a dedicated fibre cross-connect between two organizations' routers in the same building, called a PNI (Private Network Interconnect) — or publicly at an IXP (Internet Exchange Point): a shared Ethernet switching fabric in a neutral facility where hundreds of networks each plug in once and can then peer with any of the others. The largest IXPs are enormous: DE-CIX Frankfurt peaks above 17 Tbps with 1,000+ connected networks; AMS-IX Amsterdam and LINX London are of the same order.

Why this dictates where PoPs go. Putting a PoP inside an IXP building means one cross-connect gives you a direct, settlement-free, one-hop path to the users of dozens or hundreds of ISPs simultaneously. That is: lowest possible latency (one AS hop, no transit provider's backbone in the middle), lowest possible cost (settlement-free rather than per-Mbps transit), and most control (a direct link you can monitor, rather than a path chosen by someone else's BGP policy). "Number of PoPs" is the marketing number; "number of peering sessions and IXPs present at" is the number that actually predicts performance. Cloudflare publicly reports peering with 13,000+ networks; Akamai's differentiator is going one step further and placing servers inside ISP networks (§2.14).

Hold this: the internet is 75,000 ASes glued together by BGP; BGP picks paths by commercial policy first and organization-count second, and never by latency or distance; peering at IXPs is how a CDN buys a short, cheap, one-hop path to millions of users.

0.8Anycast from first principles#

You now have every piece needed to understand anycast properly rather than as magic. Section 4.2 will use it; this defines it.

The four IP addressing modes, so the word has a contrast to sit against. Unicast is one address, one destination interface — the normal case, and how ~all of the internet works. Broadcast is one address, every interface on the local segment (255.255.255.255, or ff:ff:ff:ff:ff:ff at Layer 2 — see File 01 §2.8); it does not cross routers and does not exist in IPv6 at all. Multicast is one address, every interface that has joined a specific group — used for IPTV and market-data feeds, and largely absent from the public internet because it requires cooperation from every network in the path. Anycast is **one address configured on many interfaces in many places, where the network delivers each packet to exactly one of them — whichever one the routing system considers closest.**

The mechanism, with concrete values. Suppose a CDN owns the prefix 198.51.100.0/24. It configures the address 198.51.100.42 on servers in Sydney, Tokyo, Frankfurt and Virginia, and from each of those four locations it establishes BGP sessions with local ISPs and IXP participants and **announces the identical prefix 198.51.100.0/24**. Now consider a router inside an Australian ISP. It receives, via its various BGP neighbours, several announcements for that same prefix:

ASCII diagram
  198.51.100.0/24  via AS7545 (local IXP peer)      AS_PATH: 64500          <- 1 hop
  198.51.100.0/24  via AS3356 (transit provider)    AS_PATH: 3356 64500     <- 2 hops
  198.51.100.0/24  via AS2914 (transit provider)    AS_PATH: 2914 1299 64500 <- 3 hops

It runs the decision process from §0.7, picks the first (LOCAL_PREF for peer routes, then shortest AS_PATH), and installs it. **Every packet that Australian ISP's customers send to 198.51.100.42 now goes to Sydney — not because anything knows where Sydney is, but because that announcement won the BGP tiebreak.** A German ISP's router runs the same process against its announcements and lands on Frankfurt. There is no central coordinator, no geolocation database, no measurement. Proximity is an emergent property of BGP's own preference for short, peer-learned paths.

Why it works despite sounding impossible. People's first objection is "surely the packets get split between locations and the connection breaks?" They do not, because of one property: routing is deterministic per router. A given router has one installed best path for the prefix at a given moment, so every packet of a given flow arriving at that router goes the same way. As long as (a) the flow's packets keep arriving at the same routers and (b) no BGP path change occurs mid-flow, the entire TCP connection lands consistently at one PoP.

Where that guarantee frays — the three real failure modes.

  1. A BGP reconvergence mid-flow. If a link fails or a better path appears while your TCP connection is open, the router may install a different best path and your subsequent packets arrive at a different PoP, which has no state for your connection and answers with a RST (TCP reset), killing it. For a 200 ms HTTP request this is vanishingly rare and irrelevant. For a multi-hour WebSocket connection, a large file upload, or a video conference, it is a real, observed problem — this is the "flow-stability caveat" of §4.2, and it is why raw anycast is a poor fit for long-lived stateful connections without extra machinery. The industry mitigation is a consistent-hashing layer inside each PoP plus flow-state sharing (Cloudflare's Unimog and Google's Maglev, File 01 §9.1, both solve exactly this), or simply preferring TCP-terminating designs where the reconnect is cheap.
  2. ECMP within a site. ECMP (Equal-Cost Multi-Path) is a router feature that spreads traffic across several equally-good next hops. It hashes the packet's 5-tuple (source IP, source port, destination IP, destination port, protocol) to pick a path, which keeps each flow pinned to one path. Fine — until the set of next hops changes (a server is added or removed), at which point the hash buckets shift and existing flows get rehashed to different servers. This is precisely the problem consistent hashing (File 06) exists to solve, and it is why Maglev-style hashing is a load-balancer requirement rather than a nicety.
  3. "Nearest" is BGP-nearest, not latency-nearest. Because AS_PATH counts organizations and LOCAL_PREF encodes money (§0.7), a user can be routed to a PoP that is one AS hop away but 3,000 km distant, in preference to one that is three AS hops away but in the same city. Real, measured examples of this abound — users in New Zealand landing in Los Angeles rather than Sydney, users in India landing in Singapore rather than Mumbai. Providers correct it by adjusting their announcements: AS_PATH prepending (announcing your own ASN two or three times in a row, artificially inflating the path length so that announcement loses the tiebreak and traffic shifts elsewhere), selective announcement (not announcing a prefix at certain PoPs at all), BGP communities (numeric tags attached to an announcement that request specific handling from the receiving network — e.g. "do not export this to your transit providers"), and more-specific announcements (announcing a /24 from one site and only a /22 elsewhere, since routers always prefer the longest prefix match regardless of every other attribute — this is the biggest hammer in the toolbox and the one used to steer traffic decisively).

The advantages that follow directly from the mechanism, not asserted but derived:

Who uses it, so the term is grounded: all thirteen DNS root servers are anycast (that is how 13 names serve the planet); **Google Public DNS 8.8.8.8 and Cloudflare 1.1.1.1 are anycast; Cloudflare anycasts every single customer IP from every PoP, which is the most aggressive deployment in the industry; AWS Global Accelerator** (§14.5) sells anycast entry points without caching; GCP's Global External HTTP(S) Load Balancer uses a single anycast VIP worldwide (File 01 §9.3).

Hold this: anycast is one IP announced from many places via BGP; the routers, following commercial policy and AS-hop count, deliver each user to one nearby copy; it needs no client cooperation, fails over in seconds, and is the only mechanism that dilutes a volumetric DDoS by construction.


1Architectural Definition & "The Why"#

animatedDistance is latency — the edge deletes the distance
WITHOUT A CDN — every byte crosses an ocean, twice, several times over Sydney user origin (US) ~160 ms one way · ~320 ms round trip × TCP handshake × TLS handshake × each asset edge PoP · Sydney ~5–20 ms — same city only on a MISS does the edge talk to the origin — and it reuses a warm, pre-established connection
The red path is not slow because anyone wrote bad code — it is slow because light takes ~160 ms to cross the Pacific and come back, and a page needs dozens of round trips. No amount of server optimisation touches that number. Moving the bytes to a machine in the user's city is the only lever, and that is the entire idea of a CDN.

1.1The Plain Definition#

A Content Delivery Network (CDN) is a geographically distributed network of caching proxy servers (called edge servers or Points of Presence / PoPs) that store copies of your content physically close to end users, so that requests are served from a nearby edge instead of traveling all the way to your origin server (your actual backend/data center).

A CDN is, at its heart, caching (File 02) plus geography plus smart routing (File 01). It's a cache that lives all over the world.

1.2"The Why" — The Speed of Light Is the Enemy#

Two hard physical realities forced CDNs into existence:

(1) Latency is bounded by the speed of light. Data in fiber travels at roughly 2/3 the speed of light. A round trip from Sydney to a server in Virginia (~16,000 km each way) takes ~160–200 ms minimum — no amount of faster CPUs or bigger servers can beat physics. For a page that needs dozens of round trips (DNS, TCP, TLS, HTML, then CSS/JS/images), those hundreds of milliseconds stack into seconds of load time. Users abandon slow pages; every 100 ms of latency measurably costs conversions/revenue (Amazon's famous finding). The only fix for distance latency is to reduce the distance — put the content near the user. That is the CDN's entire reason to exist.

(2) Origin bandwidth and load don't scale to the whole planet. If a video, a software update, or a viral image is fetched by 50 million people, serving all of that from your origin means:

A CDN absorbs this: the origin serves each unique object once (or a few times) to the CDN, and the CDN's thousands of edge servers serve the millions of copies to users. This is origin offload — often 90–99% of traffic never touches your origin.

1.3The Problems CDNs Solve#

ProblemHow the CDN solves it
High latency for distant usersServe from an edge PoP near the user (reduce distance)
Origin bandwidth saturationEdges serve most traffic; origin offloaded 90–99%
Origin overload / flash crowdsEdge fleet absorbs spikes; only misses reach origin
DDoS attacksMassive edge capacity absorbs/filters volumetric attacks
Slow static asset deliveryCache images/CSS/JS/video at the edge
Cost of egressCheaper CDN egress + far fewer origin fetches

Connecting to prior files: File 01 ended by noting single-region latency for far-away users needs geo routing; File 02 is caching in general. A CDN is the specific, industrial-scale answer: a globally distributed cache with geo-aware routing.


2The Recursive Sub-Concept Tree#

2.1Sub-Concept: Origin Server#

The origin is the authoritative source of the content — your web servers / object storage (e.g., an S3 bucket) / application backend. The CDN sits in front of the origin. On a cache miss, the edge fetches from the origin (an origin fetch / origin pull). A key design goal is minimizing origin fetches (maximizing offload).

2.2Sub-Concept: Edge Server / PoP (Point of Presence)#

An edge server is a caching proxy in the CDN's fleet. A PoP (Point of Presence) is a physical location (a data center) housing many edge servers, positioned in major metro areas worldwide. PoPs are often placed in/near an IXP (Internet Exchange Point) — a physical facility where many networks (ISPs, clouds, CDNs) plug into a shared switching fabric and exchange traffic directly with each other instead of paying an intermediate carrier to haul it; sitting at an IXP means the CDN is one hop from dozens of ISPs' users at once, which is exactly the low-latency, low-cost position a cache wants. Big CDNs have hundreds of PoPs across the globe. "The edge" collectively = all of them. Users are routed to a nearby PoP.

2.3Sub-Concept: Push vs. Pull CDN#

animatedPull CDN vs Push CDN
PULL — lazy, on first request user edge origin only on a miss ✔ zero setup — point DNS at the CDN and you are done ✔ you never store anything you do not serve ✘ the first user in each region eats the full origin trip ✘ a rarely-read object is cold in every PoP, forever Use for: websites, APIs, images — anything with a long tail. PUSH — eager, published ahead of time origin edge A edge B edge C ✔ no cold start anywhere — the first user is fast too ✘ you pay to store every object in every PoP, read or not Use for: big launches, video libraries, game patches.
The choice is a bet about your access pattern. Pull optimises for a long tail (most objects are rarely requested, so caching on demand is cheapest); push optimises for a known thundering herd (a launch at midnight where the first request in every region must already be warm). Almost everything on the public web is pull.

Those two bullets are the summary. Push versus pull is a genuine strategy choice with a mechanism, a worked example, complexity, and decision conditions, so Rule 4 applies in full. Here it is properly.

2.3.1 Pull CDN — full treatment#

Mechanism, step by step. You change nothing about how content is stored. You point a hostname at the CDN (a CNAME, §0.3.1) and configure an origin — the hostname or bucket the CDN should fetch from on a miss.

  1. A user requests https://cdn.example.com/hero.jpg. Anycast or GeoDNS lands them on the Frankfurt PoP.
  2. The Frankfurt edge computes the cache key (§2.7) for that request and looks it up. Nothing found: a MISS.
  3. The edge (or its shield, §5.4) opens or reuses a connection to origin.example.com and issues GET /hero.jpg, adding conditional headers if it holds a stale copy.
  4. The origin responds 200 OK with the 240 KB body and Cache-Control: public, max-age=86400.
  5. The edge writes the object to its cache keyed as computed, records an expiry timestamp of now + 86400 s, and streams the body to the user while it is still writing — a behaviour called streaming miss or pass-through fill, which matters because it means a miss costs the user the origin latency but not an extra buffering delay.
  6. Every subsequent Frankfurt request for that key within 24 hours is a HIT served from local disk or RAM in single-digit milliseconds.

Worked example with real numbers. A site serves 500 distinct images and receives 10 million image requests per day spread across 100 PoPs, with a 24-hour TTL. Origin requests per day = 500 objects × 100 PoPs × 1 fill/day = 50,000 (and with an origin shield, §5.4, it collapses to roughly 500). Out of 10,000,000 user requests, the origin sees 50,000 — an offload of 99.5%, or 99.995% with a shield. The 50,000 "slow" users (0.5% of traffic) pay one extra origin round trip each.

Pros, with the reason each is true. Zero operational burden — there is no publish step, no sync job, no state to reconcile, because the cache is populated as a side effect of real demand; the CDN is a pure read-through layer and the origin remains the sole source of truth. Automatically correct — because content is only ever fetched from the origin, an object can never be "stale in the CDN because someone forgot to re-publish"; freshness is governed entirely by TTL and validators. Storage-efficient and demand-shaped — each PoP only stores what its own users actually asked for, so a PoP in São Paulo holds Brazilian-popular objects and one in Seoul holds Korean-popular ones, without anyone configuring that. Trivially scalable to enormous catalogues — a site with 50 million images does not need 50 million objects × 100 PoPs of storage; it needs only the working set (File 02 §2.6).

Cons, with the failure mode. The first request per object per PoP is slow — the cold-miss penalty. With 100 PoPs and a 24-hour TTL, every object is fetched from origin 100 times a day and 100 unlucky users per object per day eat the full origin RTT. For a Sydney user pulling from a Virginia origin, that is a 220 ms penalty on top of everything else. Unpopular content never gets warm — an object requested twice a week at a given PoP, with a 24-hour TTL, is a miss essentially every time; the cache does nothing for the long tail. This is the one-hit-wonder problem, and measurements at large CDNs consistently find that 50–70% of distinct objects are requested exactly once at a given PoP, meaning they cost a fill and provide no benefit — which is why edges use admission policies (cache only on the second request, or use a Bloom filter — a compact probabilistic set that answers "have I seen this key before?" in a few bits per key with a tunable false-positive rate — to detect a second sighting cheaply). A traffic spike on cold content still hammers the origin — a product launch drives simultaneous misses at every PoP at once, which is exactly the thundering herd of File 02 §6.3 and exactly why origin shield and request collapsing exist (§2.11, §5.4).

Complexity/cost. Setup: minutes (one DNS record and an origin hostname). Ongoing operational cost: near zero. Origin request volume: O(objects × PoPs / TTL) without a shield, O(objects / TTL) with one. Storage at each PoP: the local working set, self-managing by eviction.

When to use it. Essentially always, for essentially everything on the web — this is the default and you should need a specific reason to deviate. Especially when the catalogue is large and access is skewed (a few objects get most requests), when content changes on an unpredictable schedule, and when you do not want a deployment pipeline that must know about your CDN.

2.3.2 Push CDN — full treatment#

Mechanism, step by step. You take responsibility for populating the cache before demand arrives.

  1. Your build or publishing pipeline produces the artifacts (a new game patch, tomorrow's episode encoded into 12 bitrate ladders, a firmware image).
  2. The pipeline uploads them to the CDN's storage or ingest API — historically over FTP/rsync, today over an HTTP API or by writing to the provider's own origin storage (Cloudflare R2, Fastly's Object Storage, Akamai NetStorage, CloudFront with an S3 origin plus a pre-warm job).
  3. The CDN replicates the objects out to PoPs — either to all of them, or to a chosen subset, on a schedule you control (typically off-peak, when spare backbone capacity is free).
  4. When the first user asks, every PoP is already a hit. There is no cold miss anywhere, ever.
  5. You are now responsible for deletion. Content stays until you remove it, so a stale or superseded object lingers and consumes paid storage until your pipeline cleans it up.

Worked example — why Netflix cannot use pull. Netflix's catalogue is on the order of hundreds of terabytes once every title is encoded into its full bitrate ladder. At 8 pm on a Friday, tens of millions of people press play within the same hour. Under a pull model, the first viewer of each title in each region triggers a multi-gigabyte origin fetch, and the aggregate first-fetch traffic at peak hour would be enormous, over exactly the links that are most congested at exactly the moment they are most congested. Instead, Open Connect (§15.1) pushes: at 3 am local time, when the ISP's network is nearly idle and transit is effectively free, Netflix's control plane copies the titles its recommendation system predicts each region will want onto the appliances sitting inside that region's ISPs. The fill happens on a network that is empty, and the serving happens from a box that is already inside the user's ISP. Netflix reports its predictive fill achieves cache-hit rates above 95% from local appliances. This is the entire argument for push at scale: it lets you move the bytes at a time and over a path of your choosing, rather than at the time and over the path your users' demand dictates.

Pros, with the reason. No cold-miss penalty, ever — the first user is as fast as the millionth, which matters enormously when the "first user" is a million people simultaneously at a launch moment. Fill traffic is scheduled — you move bytes when bandwidth is cheap and links are idle, converting a peak-hour cost into an off-peak one, which for a video service is the difference between viable and ruinous economics. Guaranteed availability of specific content — you know a given file is on a given PoP because you put it there, which is what you need for a coordinated global launch. The origin can be offline — there is nothing to pull from, so origin capacity, origin uptime and origin egress are removed from the equation entirely.

Cons, with the failure mode. You now operate a distributed publishing system, with everything that implies: partial failures (the push succeeded to 240 PoPs and failed to 12 — now some users get 404s), retries, versioning, and reconciliation. You pay storage for everything, everywhere, forever — including content nobody requests. Pushing a 50-million-object catalogue to 300 PoPs is 15 billion object-copies; the arithmetic simply does not close. Deletion becomes your problem — stale content persists until explicitly removed, so a bug in the cleanup job means users are served last week's build indefinitely. Publish latency enters your critical path — an emergency fix is not live until the push completes, which for a large artifact across a global fleet is minutes, not milliseconds.

Complexity/cost. Setup: significant (a pipeline, an ingest integration, verification, cleanup). Storage cost: O(objects × PoPs), paid continuously. Publish time: O(bytes × PoPs / fill bandwidth). Origin request volume: zero.

When to use it. When the content set is small and known in advance; when demand is simultaneous and predictable (a game release, a launch keynote, an OS update, a sports event); when the objects are very large so a cold miss is not 220 ms but 30 seconds; and when you control the release schedule and can therefore pre-position. In practice, very few organizations run a pure push CDN — the common real-world shape is pull with pre-warming, described next.

2.3.3 The hybrid everyone actually uses: pull + pre-warm#

The honest answer to "push or pull?" in a modern interview is: pull as the architecture, with selective pre-warming as an operation. You run a standard pull CDN, and immediately before a known demand spike you deliberately manufacture misses so the fill happens on your schedule rather than your users'. The mechanisms:

Decision rule, plainly stated. Use pull unless you can name a specific reason not to — it is the default for the entire web. Use push when the content is large, the catalogue is small, the demand moment is known, and you own the release schedule. Use pull with shield pre-warming when you want most of push's launch-moment benefit without operating a publishing system — which is the right answer for the overwhelming majority of real systems.

DimensionPull CDNPush CDNPull + pre-warm
Who populates the cacheUser demandYour pipelineDemand, plus a deliberate sweep
First-request latencyFull origin RTT (cold miss)Fast (already there)Fast for pre-warmed URLs
Storage costWorking set only, per PoPWhole catalogue × every PoPWorking set only
Origin must be upYes, for fillsNoYes, for fills
Deletion/cleanupAutomatic (TTL + eviction)Your responsibilityAutomatic
Scales to huge cataloguesYesNoYes
Setup effortMinutesWeeksHours
Canonical userEssentially all websitesNetflix Open Connect, game patches, OS updatesAny site with a known launch

2.4Sub-Concept: Cache Hit Ratio at the Edge (and the "cache hierarchy")#

Same metric as File 02, now geographic. A high edge hit ratio means most requests are served locally (fast, origin offloaded). To boost it, CDNs use a multi-tier cache hierarchy: an edge miss doesn't go straight to origin — it checks a regional/parent cache (a "mid-tier" or shield) first. Only a miss there hits the origin. This dramatically cuts origin load (see origin shield, 5.4).

2.5Sub-Concept: TTL & Cache-Control Headers#

The origin tells the CDN how long to cache each object via HTTP response headers (from File 02's TTL concept, now driven by HTTP):

2.6Sub-Concept: Anycast (the routing magic — full treatment in Section 4)#

Anycast is a network addressing scheme where **many physical servers, in many locations, all announce the same IP address to the internet. The internet's routing protocol (BGP) naturally delivers a user's packets to the topologically nearest** location announcing that IP. So a single IP "magically" resolves to whichever PoP is closest to each user. This is how many CDNs route users to the nearest edge without any application logic. Explained fully below.


3Deep-Dive Mechanics: How a CDN Serves a Request#

3.1End-to-End Flow (Pull CDN)#

ASCII diagram
 User in Sydney wants  https://cdn.example.com/logo.png    Origin in Virginia (US)

 1. DNS resolve cdn.example.com
      -> CDN's DNS (or Anycast IP) returns the SYDNEY edge PoP address
 2. User TCP+TLS handshake with SYDNEY edge  (~5-20 ms, not 200 ms!)
 3. GET /logo.png  ->  Sydney edge checks its cache
      3a. HIT  -> serve logo.png from Sydney. DONE. (fast, origin untouched)
      3b. MISS -> edge asks its REGIONAL/SHIELD cache
             - shield HIT  -> fill Sydney edge, serve, cache it
             - shield MISS -> ORIGIN PULL to Virginia (the one slow trip),
                              fill shield + edge, serve, cache per Cache-Control
 4. Next Sydney user for /logo.png -> HIT at the Sydney edge (fast)

The genius: the slow, long-distance trip to Virginia happens at most once per object per region (on the first miss). Every subsequent user in that region gets a fast local hit. Millions of users, one origin fetch.

3.2What CDNs Cache (and increasingly compute)#

3.3TLS & Connection Termination at the Edge#

The edge terminates TLS (File 01 concept), so the expensive TLS handshake happens over the short user↔edge hop (~20 ms), not the long user↔origin hop (~200 ms). The edge keeps warm, reused (keep-alive) connections to the origin, so even origin pulls skip repeated handshakes. CDNs also terminate the newest protocols at the edge even if your origin only speaks HTTP/1.1 — instant protocol upgrades for users. Worth defining: HTTP/2 multiplexes many concurrent requests over one TCP connection (instead of HTTP/1.1's one-request-at-a-time per connection); HTTP/3 goes further by replacing TCP itself with QUIC — a transport protocol built on UDP that bakes in TLS, cuts the handshake to one round trip (zero for repeat visitors), and eliminates TCP's head-of-line blocking (in TCP, one lost packet stalls every multiplexed stream behind it until retransmitted; QUIC's streams are independent, so a loss stalls only its own stream). For a far-away, lossy mobile connection — exactly the users a CDN serves — these handshake and loss-recovery savings are the difference between snappy and sluggish.


4Anycast & Request Routing — How Users Find the Nearest Edge#

animatedAnycast — one IP, many machines, the network does the routing
all three PoPs announce the SAME prefix (203.0.113.0/24) into BGP — routers pick the shortest path on their own PoP · London PoP · Mumbai PoP · Tokyo 203.0.113.10 203.0.113.10 203.0.113.10 user · UK user · India user · Japan failure handling is free: kill a PoP, its route withdraws, and BGP re-converges users onto the next-closest one
Anycast is the trick that makes a global network feel like a single server. Because routing decides which machine answers, there is nothing to look up, nothing to cache, and no DNS TTL to wait out during a failure. The cost is the flip side: you have very little control — the network's idea of "closest" is hop count and policy, not measured latency, and a route flap can move a live TCP connection to a different PoP and reset it.

"Route the user to the nearest edge" is the core CDN problem. There are two main mechanisms; know both and their trade-offs.

4.1Sub-Concept: BGP (Border Gateway Protocol)#

BGP is the routing protocol of the internet — it's how independent networks (Autonomous Systems, e.g., ISPs, clouds, CDNs) tell each other "to reach IP block X, send traffic through me," and how routers pick paths between them. BGP chooses routes by policy and path length (roughly, fewest network hops). You need BGP to understand anycast.

4.2Anycast Routing#

Mechanism: The CDN announces the same IP prefix from all its PoPs via BGP. When a user sends a packet to that anycast IP, the internet's routers forward it to the BGP-nearest PoP announcing it. Different users, sending to the identical IP, land on different PoPs — each on the one closest to them.

4.3DNS-Based Routing (GeoDNS / GSLB)#

Mechanism: Routing is done at DNS resolution time. When the user's resolver asks "what's the IP for cdn.example.com?", the CDN's authoritative DNS looks at who is asking (the resolver's IP, or the client subnet via EDNS Client Subnet) and returns the IP of the best PoP for that location, factoring in geography, current PoP load, and health.

Sub-Concept: GSLB (Global Server Load Balancing). GSLB is load balancing across geographic regions/data centers (as opposed to File 01's LB within one). It uses DNS (and/or anycast) to steer users to the best region based on proximity, capacity, health, and policy (e.g., latency-based, geolocation, or weighted routing — exactly AWS Route 53's routing policies). It's the "which region?" layer sitting above the "which server in this region?" layer.

4.4Anycast vs. DNS Routing — The Trade-off#

animatedAnycast vs DNS-based routing
ANYCAST decision made by: BGP, per packet failover speed: seconds (route withdrawal) granularity: whole prefix — coarse ✔ no client state, no TTL to expire ✔ absorbs DDoS by spreading it over every PoP ✘ "nearest" = fewest AS hops, not lowest latency ✘ route change mid-connection can reset TCP DNS / GSLB decision made by: the resolver's answer failover speed: bounded by the record TTL granularity: per client — fine, and steerable ✔ can weight by health, load, cost, latency data ✔ easy to shift a % of traffic for a canary ✘ resolvers ignore TTLs; failover lags reality ✘ sees the resolver's location, not the user's
Say this in an interview: they are not competitors, they are layers. Big CDNs use anycast to get you to a metro area cheaply and DNS/GSLB to make policy decisions inside it — and the honest weakness of DNS steering is that it sees the resolver's address, which is why EDNS Client Subnet had to be invented.
AspectAnycastDNS/GeoDNS (GSLB)
Proximity metricBGP path (network topology)Geo + latency + load + health
Failover speedFast (BGP reconverge)Limited by DNS TTL caching
DDoS absorptionExcellent (spreads attack)Weaker (IP is per-region)
Control granularityCoarseFine (load/health/policy-aware)
Session stabilityRare re-route riskStable per resolution

In practice CDNs combine them: anycast to get you to the nearest PoP region + internal load balancing (File 01) within the PoP, and/or DNS steering for policy control. Not either/or.


5Cache Control, Invalidation & Dynamic Content#

animatedTTL, revalidation and purge — three ways an object stops being fresh
cached at the edge · Cache-Control: max-age=3600 FRESH — served straight from RAM/SSD at the PoP, origin untouched TTL expires → STALE 1 · REVALIDATE (cheap) If-None-Match → 304 2 · stale-while-revalidate serve stale now, refresh behind 3 · PURGE (explicit) API call, propagates in seconds A 304 costs one small round trip and no body transfer — that is why ETag/Last-Modified matter so much for large files. Best practice: immutable content-hashed filenames + a one-year TTL, so you never purge — you just publish a new name.
The last line is the professional answer to "how do you invalidate a CDN?" — you design so you never have to. Hash the content into the filename (app.9f3a1c.js), set a one-year TTL, and a deploy simply references a new URL. Purging is the emergency lever, not the routine mechanism.

5.1Controlling What/How Long to Cache#

The origin drives caching via Cache-Control/s-maxage/ETag (2.5). Best practices:

5.2Revalidation (Conditional Requests)#

When a cached object's TTL expires, the edge doesn't always re-download it. It sends a conditional request to the origin: If-None-Match: <ETag> or If-Modified-Since: <date>. If unchanged, the origin replies **304 Not Modified** (tiny, no body) and the edge just refreshes the TTL on its existing copy. Saves bandwidth — you only re-transfer when content actually changed.

5.3Purging / Invalidation#

To force-remove content before its TTL (e.g., you published a correction, or bad data got cached):

Purges propagate to all PoPs; fast global purge (sub-second across hundreds of PoPs) is a headline CDN feature.

5.4Sub-Concept: Origin Shield#

animatedOrigin shield — one more layer so the origin sees almost nothing
WITHOUT SHIELD edge edge edge edge origin ×N misses every PoP misses independently, so a 200-PoP CDN can hit your origin 200× WITH SHIELD edge edge edge edge shield PoP origin ×1 the shield collapses N misses into one fetch — origin load drops by orders of magnitude
This is §6.3's cache stampede, replayed at continental scale: a popular object expiring means every PoP misses simultaneously. The shield is simply a designated mid-tier cache that all edges fetch through, turning a fan-in of 200 into a fan-in of 1 — at the cost of one extra hop of latency on a miss.

An origin shield is a designated single PoP (or small tier) that sits between all other edges and the origin. All edge misses funnel through the shield; only shield misses hit the origin. Benefits:

5.5Caching Dynamic & Personalized Content#

Naively, "dynamic = uncacheable." Modern practice says otherwise:


6Edge Protocol Optimizations — TLS, HTTP/2, QUIC, Compression#

Section 5 covered what the edge caches. This section covers the other half of a CDN's value, which applies even when the cache misses: the edge speaks the transport protocols better than your origin possibly can, because it is physically close to the user and the protocols are all latency-sensitive.

6.1TLS at the edge — killing the handshake round trips#

Recall the round-trip accounting from §0: before a single byte of your HTML moves, the browser needs DNS resolution, a TCP handshake (1 RTT), and a TLS handshake (1 RTT for TLS 1.3, 2 for TLS 1.2). On a 150 ms transcontinental link that is 300–450 ms of pure setup. Terminate that at an edge 10 ms away and the same setup costs 20–30 ms — a saving that no amount of backend optimization could ever produce, because the backend was never the problem.

Session resumption removes even more. On a repeat visit, TLS lets the client present a session ticket — an encrypted blob containing the previously negotiated secret, which the server can decrypt and reuse — so the expensive asymmetric key exchange is skipped entirely (File 02 §2.6 covers the cryptography). The CDN-specific problem, and the reason this is worth teaching: a session ticket is only useful if the server that receives it can decrypt it. With hundreds of edge servers in a PoP and hundreds of PoPs, a returning user landing on a different machine gets a full handshake unless the ticket keys are shared. Every serious CDN therefore distributes and rotates a common set of session-ticket keys across its fleet — and does so carefully, because a ticket key that never rotates undermines forward secrecy (an attacker who eventually steals the key can decrypt every recorded session that used it). The trade-off in one line: share ticket keys widely for performance, rotate them frequently for security, and those two pull in opposite directions.

TLS 1.3 0-RTT goes further: on a resumed connection the client sends application data in its very first packet, alongside the handshake, for an effective zero round trips. The cost is a real security property: 0-RTT data is replayable — a network attacker who captures that first flight can re-send it, and the server cannot distinguish the copy from the original. That is harmless for a GET of a cacheable asset and dangerous for anything that changes state. The rule: enable 0-RTT for idempotent GETs only, never for POST/PUT/DELETE (File 15 covers idempotency properly). Every CDN that offers 0-RTT enforces some version of this rule, and knowing why it exists is the interview-grade answer.

6.2HTTP/2 — multiplexing, and the problem it did not solve#

HTTP/1.1's defect: one request at a time per connection. A page needing 80 assets either serialized them or forced the browser to open ~6 parallel connections per host (each with its own handshake and its own slow-start), which is why the era's optimizations were sprite sheets, file concatenation, and domain sharding — all workarounds for a protocol limit.

HTTP/2's fix — multiplexing. One TCP connection carries many concurrent streams, each an independent request/response, with frames from different streams interleaved on the wire. Eighty assets now travel over one warm connection. It adds HPACK header compression (headers repeat almost identically across requests; HPACK keeps a shared dynamic table so the second request's headers cost a handful of bytes instead of several hundred) and stream prioritization (the client can say "the stylesheet before the footer image").

What it did NOT fix, and this is the point of §6.3: TCP head-of-line blocking. All those streams ride one TCP connection, and TCP guarantees in-order delivery of the whole byte stream. Lose one packet belonging to the image, and TCP will not deliver any subsequent bytes to the application — including the completed stylesheet — until the lost packet is retransmitted. On a clean network HTTP/2 is a large win; on a lossy mobile network it can be worse than HTTP/1.1 with six connections, because six connections means a loss stalls only one sixth of your traffic. That surprise is exactly what motivated QUIC.

6.3HTTP/3 and QUIC — what actually changed#

QUIC is a transport protocol built on UDP rather than TCP, and HTTP/3 is HTTP mapped onto it. Building on UDP was not an aesthetic choice: TCP is implemented in operating-system kernels and in middleboxes across the internet, so changing it takes a decade; UDP is a thin wrapper the application can build on top of, so QUIC ships as a library and can evolve at software speed. Four concrete improvements:

The costs, stated honestly: QUIC runs in user space, so it consumes noticeably more CPU per byte than kernel TCP (a real cost at CDN scale, being closed by kernel offloads); some corporate firewalls block or throttle UDP, so clients must fall back to HTTP/2; and debugging is harder because the packets are encrypted. Deployment reality: browsers try HTTP/3 when advertised (via the Alt-Svc header or the DNS HTTPS record) and fall back silently, so it is a safe thing to enable at the edge — and this is precisely the kind of upgrade a CDN gives you for free, since your origin can keep speaking HTTP/1.1 while the edge speaks HTTP/3 to users.

6.4Compression at the edge#

Text compresses enormously — HTML, CSS, JavaScript, and JSON typically shrink 60–80% — and that reduction is multiplied by the number of users, making it one of the highest-leverage optimizations available. The algorithm choice is a CPU-versus-ratio trade:

Negotiation happens through the Accept-Encoding request header, and the response must carry Vary: Accept-Encoding (File 02 §7.4) or a shared cache will hand a Brotli body to a client that cannot decode it. What not to compress: already-compressed formats (JPEG, PNG, WebP, MP4, ZIP) — you burn CPU to make them marginally larger.

Image and media optimization belongs here too, because it usually dwarfs text savings: the edge can transcode a JPEG to WebP or AVIF based on the client's Accept header (AVIF is commonly 50% smaller than JPEG at equal quality), resize to the device's actual display size, and strip metadata. Doing this at the edge rather than at build time means one canonical original serves every device — at the cost of a cache entry per variant, which again is a Vary and cache-key design problem.


7Dynamic Content Acceleration — Why a CDN Helps Even When Nothing Is Cacheable#

The most common misconception about CDNs is that they are only for static files. A CDN meaningfully accelerates a personalized, uncacheable API response, and the mechanism is worth understanding because it is the answer to "why put a CDN in front of an API?"

Where the time actually goes. Consider a user in Sydney calling an origin in Virginia, RTT ≈ 200 ms, with the origin taking 50 ms to compute the response.

ASCII diagram
   DIRECT TO ORIGIN                            VIA CDN EDGE (5 ms away)
   DNS ................  (cached)              DNS ................  (cached)
   TCP handshake ......  200 ms                TCP handshake ......   10 ms
   TLS 1.3 handshake ..  200 ms                TLS 1.3 handshake ..   10 ms
   Request + response .  200 ms + 50 ms        Edge->origin (warm, no handshake,
                                                already-open connection)  200 ms + 50 ms
   TCP slow start:                             TCP slow start to user: negligible
     several extra RTTs for a large body         (short RTT, window grows in ms)
   --------------------------------            --------------------------------
   TOTAL ~ 650 ms+                             TOTAL ~ 270 ms

Four distinct mechanisms produced that difference, and you should be able to name each:

  1. Handshake termination near the user (§6.1) — the two setup round trips shrink from 200 ms each to 10 ms each.
  2. Connection reuse to origin. The edge maintains a pool of long-lived, already-warm connections to your origin. The user's request does not pay for establishing one; it borrows an existing one. Over many users this is the difference between your origin handling millions of handshakes and handling almost none.
  3. TCP slow start avoidance — the underrated one. TCP does not begin at full speed; it starts with a small congestion window (about 10 packets, ~14 KB) and doubles it each round trip until it detects loss. Over a 200 ms RTT, growing the window enough to send 200 KB takes several round trips — so a large response is slow even on a fast link, purely because of RTT. On the edge-to-user leg the RTT is 10 ms, so the window grows to full size in tens of milliseconds. Meanwhile the edge-to-origin connection is long-lived and already has a fully-grown window. You have replaced one cold long-RTT connection with one warm long-RTT connection plus one short-RTT connection, and that is a large win independent of caching.
  4. Better routing. Public internet paths between two points are chosen by BGP for policy and cost, not for latency, and can be badly indirect. Traffic entering a CDN's edge travels the rest of the way over the provider's private backbone with optimized routing and no congested peering points — commonly 20–40% faster than the public path, and far more consistent.

The honest limits. If your origin takes 2 seconds to generate the response, the CDN saves you 400 ms of a 2.4-second experience — real, but your problem is the origin. And a CDN cannot help a first byte that must be computed. Say this in an interview: "a CDN removes network overhead, not compute time."

Techniques that convert 'uncacheable' into 'partly cacheable': cache the page shell and fetch the personalized fragment separately (so the shell is a global cache hit); use Edge Side Includes or edge compute (§9) to assemble a page from cached and dynamic fragments at the edge; and mark responses private, no-store only where genuinely necessary rather than reflexively across a whole API.


8Video & Large-File Delivery#

Video is where CDNs earn most of their revenue and where the mechanics differ enough from ordinary web delivery to deserve their own treatment.

8.1Why video cannot be delivered as one file#

A two-hour film at a good bitrate is several gigabytes. Delivering it as a single object would mean the viewer waits for a large prefix before playback, any network dip stalls the stream, seeking to the middle requires either downloading everything before it or complex range logic, and a viewer on a slow connection gets the same enormous file as one on fibre. The fix that the entire industry converged on: cut the video into small, independently-fetchable segments, and encode several quality versions of each.

8.2Segmentation, manifests, and adaptive bitrate#

The video is transcoded into a ladder of renditions — for example 240p at 400 kbps, 480p at 1 Mbps, 720p at 2.5 Mbps, 1080p at 5 Mbps, 4K at 15 Mbps — and each rendition is cut into segments of typically 2–10 seconds. A manifest file lists the renditions and their segment URLs.

Adaptive bitrate (ABR) is the client-side algorithm that exploits this. The player measures how fast recent segments arrived and how full its buffer is, and chooses the rendition for the next segment accordingly: buffer healthy and throughput high, step up a rung; buffer draining, step down immediately. The result the user perceives: playback starts fast at low quality and improves within seconds, and a network dip causes a visible quality drop instead of a stall. The trade-offs: shorter segments adapt faster and let playback start sooner, but multiply the request count and add per-segment overhead; longer segments compress slightly better and reduce request volume, but react sluggishly and increase startup delay. Two to six seconds is the usual compromise, with low-latency variants using shorter chunks.

The two formats. HLS (HTTP Live Streaming, from Apple) uses .m3u8 playlists and is universally supported, mandatory on iOS. MPEG-DASH is the open standard, codec-agnostic, using an XML manifest. They differ in packaging more than in concept, and CMAF exists precisely so one set of segment files can serve both, halving your storage and — more importantly — halving your cache footprint, since otherwise the CDN caches two copies of every segment.

Why this is ideal for a CDN: every segment is an immutable, cacheable file at a stable URL. Ten thousand viewers of the same live stream in one city request the same segment within seconds of each other, so one origin fetch serves all of them. The CDN's origin-offload ratio for popular video approaches 100%.

8.3Live streaming and its extra constraints#

Live adds a hard constraint absent from on-demand: glass-to-glass latency, the delay between the event happening and the viewer seeing it. Standard HLS/DASH with 6-second segments and a 3-segment buffer gives 20–30 seconds of latency — unacceptable for sports or auctions where a neighbour's cheer arrives before your picture. Low-Latency HLS and LL-DASH cut this to 2–5 seconds by delivering partial segments as they are encoded, using chunked transfer so the player begins consuming a segment before it is complete. Sub-second latency requires abandoning HTTP segments entirely for WebRTC, which trades CDN cacheability for interactivity.

The other live-specific problem is the origin thundering herd: at the instant a new segment becomes available, every edge in the world requests it simultaneously. The fixes are the ones you already know from File 02 §6.3: request coalescing at the edge (one origin fetch per PoP regardless of how many users are waiting), and an origin shield tier so that all PoPs collapse into a single origin request.

8.4Byte-range requests and large downloads#

For large non-video files (software updates, game patches, datasets), the mechanism is HTTP range requests: the client sends Range: bytes=1048576-2097151 and receives 206 Partial Content. This enables resumable downloads after an interruption, parallel fetching of several ranges at once to saturate a link, and seeking within a file.

The CDN consequence you must understand: a cache must decide whether to store the whole object on a range request or only the requested slice. Storing whole objects wastes bandwidth when clients only ever want fragments; storing slices fragments the cache and complicates invalidation. Real CDNs support both, typically by splitting large objects into fixed-size internal blocks and caching those independently — so a request for byte 5,000,000 fetches only the block containing it. The operational implication: your origin must correctly support range requests (many application servers do not, or do so incorrectly for dynamically-generated bodies), or large-file delivery degrades badly.


9Edge Compute#

Once a provider operates hundreds of PoPs with servers milliseconds from every user, running your code there is a small step — and it changes what the edge can do from "serve what I stored" to "decide, transform, and generate."

9.1The execution models, and why they differ#

9.2What genuinely belongs at the edge#

9.3What does not belong at the edge#

Anything requiring strongly consistent state. Edge state is by nature distributed across hundreds of locations, so it is eventually consistent unless the platform provides a specific coordination primitive (Cloudflare's Durable Objects exist precisely to give you a single-threaded, single-location object when you need serialization). The failure to avoid: implementing a counter, a lock, or an inventory decrement in edge storage and assuming it behaves like a database. It does not — you have reinvented multi-leader replication and its conflicts (File 08).

Also unsuited: long-running or CPU-heavy work (the limits are tight and the pricing punishes it), anything needing a large dependency tree, and anything requiring a private database connection your VPC would have to expose globally.

The general rule: the edge is for decisions and transformations on the request path, not for computation and state.


10Security at the Edge#

A CDN is a security product as much as a performance one, because a distributed edge is structurally capable of things a single origin can never be.

10.1DDoS absorption — why only an edge can do this#

A volumetric DDoS attack floods you with more traffic than your links can carry. Note carefully what that means: the defence is not clever filtering, it is capacity. If an attacker can generate 2 Tbps and your datacenter has 100 Gbps of connectivity, no firewall you install helps — your pipes are full before any software sees a packet. A major CDN operates hundreds of Tbps of aggregate capacity spread across hundreds of PoPs, and because it uses anycast (§4), the attack is automatically divided among all of those PoPs by the internet's own routing: traffic from a botnet in Brazil lands in São Paulo, traffic from Europe lands in Frankfurt, and no single location sees the whole flood. That structural property — the attack is split by the same mechanism that splits legitimate users — is the entire reason edge DDoS protection works and origin DDoS protection does not.

Attack classes, so you can distinguish them:

10.2WAF, bot management, and rate limiting#

The WAF (Web Application Firewall) inspects requests against rule sets — managed rules for known attack signatures (SQL injection, cross-site scripting, path traversal, and specific published CVEs) plus your custom rules. The trade-off you must state: rules can produce false positives that block real users, so the discipline is to deploy new rules in log-only mode first, review what would have been blocked, and only then enforce.

Bot management distinguishes automated traffic from human, using signals a simple IP block cannot: TLS fingerprints (JA3/JA4 — the ordering and set of parameters in the TLS handshake, which varies by client library and is much harder to forge than a user agent), HTTP/2 fingerprints, behavioural analysis, and reputation. Responses escalate: allow, challenge (a JavaScript proof-of-work or a CAPTCHA), throttle, or block. The nuance worth voicing: you want to block scrapers while allowing search-engine crawlers and your own monitoring, so bot management is always allow-listing plus classification, never a blanket rule.

Edge rate limiting is File 03's topic enforced at the cheapest possible place — see File 03 §8.1 for the mechanics and the accuracy trade-off of counting across PoPs.

10.3Origin protection — the step people forget#

All of the above is worthless if an attacker can bypass the CDN and hit your origin's IP directly, and origin IPs leak constantly (through DNS history, TLS certificate transparency logs, mail server records, or a subdomain that was never proxied). You must lock the origin so it only accepts traffic from the CDN. In increasing order of strength:

10.4Protecting private content and the cache-poisoning class of bugs#

Signed URLs and signed cookies let a CDN serve private content without consulting your origin per request: you generate a URL containing an expiry and an HMAC signature over the path and expiry; the edge validates the signature with a shared key and serves or refuses. The trade-offs: a signed URL is bearer authority — anyone who obtains it within its validity window can use it, so keep expiries short — and you cannot revoke an issued URL before expiry without rotating keys.

Cache poisoning is the failure mode that turns a CDN into an attack amplifier: if an attacker can get a malicious response stored under a key that legitimate users will request, the CDN serves that response to everyone. The two common routes are unkeyed input (a request header influences the response but is not part of the cache key — the attacker sends a poisoned X-Forwarded-Host, the origin reflects it into the page, and the edge stores it under the ordinary URL) and cache deception (tricking the cache into storing a personalized page by requesting /account/settings.css, where the origin ignores the extension and serves the account page while the edge sees ".css" and caches it as a static asset). The defences: include in the cache key every input that can affect the response (or strip those inputs entirely), never let the origin reflect unvalidated headers, and configure caching by explicit Cache-Control from the origin rather than by file extension. This is the security face of the key-design rule in File 02 §2.7.


11Measuring a CDN#

You cannot manage what you do not measure, and CDN metrics have specific traps.

Cache hit ratio, measured at the right layer. The headline number is hits / (hits + misses), but a single figure hides the structure: the edge hit ratio is what determines user latency, while the origin offload ratio (the fraction of requests your origin never sees, counting shield hits) is what determines your origin bill and capacity. With a shield tier they differ substantially — an 85% edge hit ratio plus a shield absorbing most of the remainder can still mean 97% origin offload. Report both, and be suspicious of anyone quoting one without the other.

Two ratios also differ by unit: request hit ratio versus byte hit ratio. A CDN can hit on 95% of requests (all the small assets) while missing on the few large video segments that constitute most of the bytes. If you care about origin egress cost, the byte ratio is the one that matters.

Why the hit ratio is lower than you expect, and what to do: the usual causes are cache-key fragmentation from query strings and over-broad Vary (File 02 §7.4), TTLs that are too short, uncacheable Set-Cookie headers attached to static responses (many frameworks do this by default and it silently disables caching for those objects), and a long tail of rarely-requested objects that expire before they are requested twice. Diagnose by grouping hit ratio by path prefix and content type rather than looking at the global number.

Latency, measured where it matters. Edge-reported latency measures the edge's own service time and is flattering. Real User Monitoring (RUM) — instrumentation in the browser reporting actual timings from actual users — is the source of truth, because it includes DNS, connection setup, and the last-mile network that the CDN cannot see. Track it by geography and by percentile; a global p50 tells you nothing about the region where your CDN has poor presence, and the p99 is where the users who leave live.

Origin metrics as the control. Watch origin request rate, origin bandwidth, and origin error rate. A sudden rise in origin traffic with no traffic increase means your hit ratio has collapsed — usually because a deploy changed URLs, a header changed the cache key, or someone purged everything.

Cost metrics. CDN pricing is per-GB delivered plus per-request, varying by region (delivery in South America and Asia-Pacific commonly costs several times more than in North America or Europe). The number to compute is your effective cost per GB delivered and the origin egress avoided, since the whole financial argument for a CDN is that its per-GB rate is lower than your cloud provider's egress rate and that you serve far fewer bytes from origin.


12Pros, Cons & Trade-offs#

12.1Benefits#

12.2Costs & Trade-offs#


13Interview Diagnostic Framework (Symptom → Solution)#

System SymptomWhy a CDN is the cureSpecific solution
"Users in Tokyo have 300 ms latency; US users are fine."Distance latency; only fix is reducing distance.CDN with an Asian PoP serving cached content locally.
"Our origin bandwidth/NIC is saturated serving images/video."Origin can't serve the planet.CDN edge caching (+ origin shield) offloads 90–99%.
"A viral post melts our origin every time."Flash crowd hits origin.CDN edge absorbs the spike; request collapsing + shield.
"Video buffers / slow to start for global users."Segments fetched from far origin.CDN caches HLS/DASH segments at the edge.
"We're getting volumetric DDoS'd."Attack concentrates on origin.Anycast CDN spreads/absorbs the attack; edge WAF.
"Deploys serve stale JS/CSS to some users."Bad invalidation.Fingerprinted (content-hash) filenames + long TTLs.
"We need to personalize but still want edge speed."Dynamic seems uncacheable.Micro-caching + ESI + edge compute (Workers).
"Cross-continent egress bill is huge."Origin egress cost.CDN offload reduces origin fetches + cheaper edge egress.

14Real Implementations & Product Landscape#

"Put a CDN in front of it" names a category containing products with genuinely different architectures, strengths, and pricing models. This section is what you actually choose between.

14.1Family 1 — Full-service global CDNs#

Akamai. The oldest (founded 1998 out of MIT research on exactly the content-distribution problem this file describes) and still the largest by footprint, with servers in thousands of locations. Its distinguishing architectural choice is deep embedding: rather than a few large datacenters, Akamai places servers inside ISP networks, physically as close to end users as it is possible to get without being in their house. That is why it remains the choice for the largest media events and software distributions — when Apple ships an OS update to a billion devices, the last mile is the whole problem. It is also the most feature-dense platform (an enormous configuration surface, extensive security products, sophisticated media delivery).

Cloudflare. Founded 2009, distinguished by running every service from every location — anycast (§4) across all PoPs, with DDoS protection, WAF, DNS, and Workers all executing at the same edge rather than in separate tiers. Its second distinguishing choice is commercial: an unusually capable free tier with unmetered DDoS protection and, notably, no charge for bandwidth on its CDN plans for standard web content — a direct attack on the industry's per-GB model. Workers (§9.1) is the most mature edge-compute platform, and R2 offers S3-compatible object storage with zero egress fees, which is strategically aimed at AWS's egress pricing.

Fastly. Founded 2011 around two design bets. First, instant purge: cache invalidation propagates globally in roughly 150 milliseconds, versus tens of seconds elsewhere — which changes what you can cache, because you can cache genuinely dynamic content (a news homepage, a stock page, an inventory count) and purge it the instant it changes, rather than choosing a short TTL. Second, programmability: originally VCL (the Varnish Configuration Language — see File 02 §10.3) and now Compute running WebAssembly, letting you express complex caching and routing logic as code. Fastly deliberately runs fewer but larger PoPs than Akamai, betting that well-connected large nodes beat many small ones.

AWS CloudFront. The default when you are already on AWS, and its argument is integration rather than raw superiority: origin access control to S3 buckets that are otherwise fully private, native ACM certificates, WAF and Shield integration, Lambda@Edge and CloudFront Functions (§9.1), and Origin Shield as a configurable mid-tier. Its most important commercial property: data transfer from S3 (or EC2) to CloudFront is free, and CloudFront's own egress rates are lower than direct S3 egress — so putting CloudFront in front of S3 frequently reduces your bill rather than adding to it. Limits: configuration changes historically propagate slowly; invalidations are slower and charged beyond a free allowance (the standard workaround is versioned object names, §5); and it is less compelling if your origin is not on AWS.

Google Cloud CDN and Media CDN ride Google's private backbone with a single global anycast IP, tightly coupled to Google Cloud Load Balancing; Media CDN is the separate product built on the YouTube delivery infrastructure for large-scale video. Azure Front Door occupies the same position for Azure, combining global load balancing, CDN, and WAF.

14.2Family 2 — Value and specialist providers#

BunnyCDN competes on price and simplicity with per-GB rates a fraction of the enterprise providers', plus a straightforward video-streaming product. Best at: cost-sensitive projects with ordinary requirements. Limits: fewer enterprise features and less security depth.

Cloudflare R2, Backblaze B2, and Wasabi are storage rather than CDN, but they belong in this discussion because egress pricing is often the dominant cost in a content-delivery architecture. R2 charges zero for egress; B2 and Wasabi charge little or nothing under fair-use terms; S3 charges meaningfully per GB. Pairing cheap-egress storage with a CDN is one of the highest-leverage cost decisions available, and the Bandwidth Alliance exists precisely so that traffic between member storage providers and member CDNs is not double-billed.

14.3Family 3 — Private and purpose-built CDNs#

Netflix Open Connect is the canonical example of building rather than buying, and it is worth understanding as an architecture. Netflix places its own hardware appliances — Open Connect Appliances, essentially dense storage servers — directly inside ISP networks and at internet exchanges, given to ISPs at no cost because it saves the ISP transit bandwidth. Content is pushed (§ the push-vs-pull discussion earlier) during off-peak hours, using Netflix's own prediction of what will be watched in that region tomorrow, so at peak time the content is already there and the stream never crosses the wider internet. Why this is only right for Netflix: it requires a catalogue small enough to preposition, viewing patterns predictable enough to forecast, volume large enough to justify hardware, and the organizational capacity to run a global hardware fleet. The takeaway to state in an interview: build your own CDN only when your traffic is a large fraction of the internet's and your content is predictable; otherwise the economics are ruinous.

Meta, Google, and Apple operate comparable private edge networks for the same reasons.

14.4Family 4 — Framework and platform edges#

Vercel, Netlify, Deno Deploy, and Cloudflare Pages bundle a CDN with a deployment platform: you push code, and static assets are distributed to the edge while server-rendered routes execute at edge or regional functions. Best at: developer velocity for web applications, with caching configured largely by convention. Limits: you inherit their CDN choices, cost scales differently (per-invocation and per-seat rather than purely per-GB), and heavy media delivery is usually not the sweet spot. Note the layering honestly: several of these run on top of the providers above, so you are choosing a developer experience, not an independent network.

14.5Adjacent products people confuse with CDNs#

AWS Global Accelerator provides anycast IPs and routes traffic over AWS's backbone to your regional endpoints — it delivers the routing and TCP termination benefits of §7 but does not cache anything. It is the right answer for accelerating non-HTTP protocols or a stateful TCP/UDP service; it is the wrong answer if you wanted caching. Confusing these two is a common interview error.

DNS-based global traffic managers (Route 53 latency/geolocation routing, NS1, Akamai GTM) steer users to regions at resolution time with no data path at all — see File 01 §9.4 for why TTL caching makes this a coarse instrument.

Image and video CDNs (Cloudinary, imgix, Mux) are specialist layers combining transformation with delivery, worth naming when the media pipeline itself is the problem rather than the distribution.

14.6Comparison table#

ProviderPoP modelPurge speedEdge computeSecurity depthPricing shapeBest for
AkamaiThousands, embedded in ISPsSecondsEdgeWorkersVery deepEnterprise contract, $$$$Largest-scale media & software delivery
CloudflareHundreds, all services everywhereSeconds (instant with tags)Workers (V8 isolates, best-in-class)Very deep, unmetered DDoSFree tier; plan-based, bandwidth-inclusiveSecurity + performance + edge compute
FastlyFewer, larger, well-peered~150 ms globalCompute (WASM)Strong (WAF, bot)Per-GB + per-requestDynamic caching, programmable edge
CloudFrontHundreds + regional edge cachesSlower, charged past free tierLambda@Edge, CloudFront FunctionsWAF + ShieldPer-GB (free from S3/EC2)AWS-native stacks
Google Cloud CDN / Media CDNGoogle backbone, single anycast IPFastCloud Run/Functions adjacencyCloud ArmorPer-GBGCP stacks; large-scale video
Azure Front DoorMicrosoft edgeFastRules engineWAF integratedPer-GB + routing rulesAzure stacks
BunnyCDNBroad, low-costFastEdge scriptingBasicVery low per-GBCost-sensitive standard delivery
Netflix Open ConnectAppliances inside ISPsn/a (push)n/an/aOwn hardwareOnly if you are Netflix-scale
Vercel / NetlifyRides other networksDeploy-triggeredEdge functionsBasicPer-seat + usageWeb app developer velocity
Global AcceleratorAWS anycast, no cachen/aShieldHourly + per-GBNon-HTTP acceleration, static IPs

14.7Decision rules#

14.8Anti-recommendations#


15Real-World Engineering Scenarios#

15.1Netflix — Open Connect (a purpose-built CDN)#

Netflix is ~15% of global internet traffic at peak; a generic CDN couldn't do it economically, so they built Open Connect:

  1. Netflix ships Open Connect Appliances (OCAs) — their own caching servers — and places them inside ISP networks and at IXPs, as close to viewers as physically possible (often in the subscriber's own ISP).
  2. During off-peak hours, Netflix proactively pushes (predictive fill) the next day's likely-popular titles to the OCAs — a push CDN using their recommendation data to pre-position content. So when you hit play, the video streams from a box inside your ISP — minimal latency, zero long-haul.
  3. The control plane (which OCA should serve you) uses health/proximity/capacity steering (GSLB-style); the video segments are the cached objects.
  4. Takeaway: at extreme scale you push content predictively to edges inside ISPs; separate the control plane (routing) from the data plane (segment serving).

15.2Cloudflare — Anycast Everything#

Cloudflare fronts a huge fraction of the web:

  1. Every Cloudflare IP is anycast — announced from all ~300+ PoPs. A user's request lands at the nearest PoP purely via BGP, no GeoDNS needed.
  2. Anycast gives them industry-leading DDoS absorption: a volumetric attack against a customer's anycast IP is automatically spread across every PoP's capacity, diluting it.
  3. At the edge they run Workers (edge compute) for auth, redirects, personalization, and even full apps, plus WAF and bot management — all executing near the user, not at origin.
  4. They use tiered caching / origin shield so edge misses funnel through a parent cache before hitting the customer origin.
  5. Takeaway: anycast is the routing backbone; edge compute + tiered caching turn the CDN into a global application platform.

15.3Amazon CloudFront + S3 — The Canonical Static Site / Asset Stack#

  1. Static assets — or a whole SPA (Single-Page Application: a web app delivered as one HTML shell plus JS bundles that render everything client-side and talk to APIs, so the entire UI is static files, perfectly cacheable) — live in an S3 bucket (the origin — File 09 territory). CloudFront (pull CDN) sits in front.
  2. Route 53 (DNS/GSLB) with latency-based routing + CloudFront's own edge network route users to the nearest of hundreds of edge locations. TLS (ACM cert) terminates at the edge.
  3. Assets use **content-hashed filenames + Cache-Control: max-age=31536000, immutable; the HTML has a short TTL. Deploys upload new hashed files and update HTML → instant, invalidation-free cache-busting. Origin Shield** (a regional edge cache) is enabled to minimize S3 GET requests.
  4. On a purge need, CloudFront invalidation clears specific paths.
  5. Takeaway: the standard cloud pattern — object storage origin + pull CDN + DNS-based geo routing + fingerprinted immutable assets + origin shield.

16Interview Gotchas & Failure Modes#

16.1Classic Questions#

16.2Failure Modes & Mitigations#


17Whiteboard Cheat Sheet#

ASCII diagram
   Users (worldwide)
       │  DNS/Anycast picks NEAREST PoP  (GSLB: geo+latency+load+health, or BGP anycast)
       ▼
  ┌─────────┐  ┌─────────┐  ┌─────────┐   ... hundreds of PoPs (edge servers)
  │ PoP Tokyo│  │PoP London│  │PoP Sydney│   each = cache + TLS term + WAF + edge compute
  └────┬────┘  └────┬────┘  └────┬────┘
       │ miss       │ miss       │ miss
       └────────────┴──── ORIGIN SHIELD (mid-tier cache, request collapsing) ────┐
                                                                                  ▼
                                                                          ┌──────────────┐
                                                                          │   ORIGIN     │  served ~once
                                                                          │ (S3 / backend)│  per object/region
                                                                          └──────────────┘

ROUTING:   Anycast (BGP -> nearest, great DDoS/failover, coarse)
           GeoDNS/GSLB (DNS -> best PoP by geo/load/health, fine control, DNS-TTL lag)
FILL:      Pull (lazy on first miss, default) | Push (pre-position known-popular, e.g. Netflix)
CACHE-CTRL: max-age/s-maxage, ETag(304 revalidate), immutable + content-hash filenames (cache-bust)
DYNAMIC:   micro-cache(1-5s) | ESI fragments | stale-while-revalidate / stale-if-error | edge compute
OFFLOAD:   origin shield + request collapsing => origin sees ~1 fetch, not N PoPs
DANGER:    never cache private/auth responses publicly (Cache-Control: private/no-store)

One-sentence summary for an interviewer:

"A CDN is a globally distributed cache that beats the speed-of-light latency floor by serving content from an edge PoP near the user and offloads 90–99% of traffic from the origin; users reach the nearest edge via anycast (BGP) and/or GeoDNS/GSLB (policy-aware), content is filled pull (lazy) or push (pre-positioned like Netflix), an origin shield collapses misses so the origin is fetched ~once, static assets use fingerprinted immutable URLs to sidestep invalidation, and you must never publicly cache private/authenticated responses."


End of File 05. Next → File 06: Consistent Hashing (hash rings, virtual nodes, minimal rehashing) — the algorithm we've foreshadowed in Files 01, 03, and 04.