Content Delivery Networks

Picture a news site publishing a single breaking-story photo. Ten million people request it within an hour. If every request travels to one origin server, the origin's uplink saturates. Latency balloons, and the site effectively goes down under legitimate demand alone. Yet the same photo, once fetched, is identical for every user. There is no reason to fetch it from the same distant server ten million times. This redundancy is exactly the problem a Content Delivery Network (CDN) exploits. Cache the object close to users, and answer most requests without ever touching the origin. CDNs sit at the intersection of two ideas already familiar from DNS: The Internet Naming System and HTTP and the Web. These are a naming system that can return different answers to different askers, and a request/response protocol whose responses are cacheable. A CDN turns these into a global replica-placement and traffic-steering system. It answers three coupled questions: where should copies of content live, how does a request find the nearest useful copy, and what happens when the nearest copy does not have the answer. In real systems, CDNs are not a boutique optimization. They are the substrate the modern web runs on. A large fraction of global HTTP(S) traffic, video streaming, software updates, and API calls never reaches the origin infrastructure of the company operating the service. Instead, it is served from edge points of presence (PoPs) operated by CDN providers. Getting replica placement and redirection right is what makes a website feel instantaneous in Tokyo and in São Paulo simultaneously, using one origin in Virginia. This article builds the CDN model from first principles. It covers the caching hierarchy, the placement and eviction problem, and the two dominant redirection mechanisms (DNS-based and anycast/HTTP-based). It also explains how a CDN decides "closest" in a way that is provably better than naive geographic distance. It closes by connecting CDNs to the security perimeter role they increasingly play, foreshadowing DDoS Attacks and Mitigation.

Key takeaways
  • A CDN replicates content across geographically distributed edge servers so requests are served near the client, cutting latency and origin load.
  • Server selection is the core algorithmic problem: map each client to a "good" edge server using DNS redirection, anycast, or HTTP redirects.
  • Caching follows a hierarchy (browser → edge → regional → origin), with cache-miss requests pulled through on demand ("pull" CDNs) or pre-pushed ("push" CDNs).
  • Replica placement is a facility-location problem: minimizing expected latency/cost subject to storage and bandwidth constraints, solved heuristically at Internet scale.
  • DNS-based redirection exploits the recursive resolver's IP as a (noisy) proxy for client location; anycast exploits BGP routing to reach the topologically nearest instance.
  • CDNs blur into security infrastructure — the same edge layer that absorbs traffic spikes also absorbs attack traffic, which is why CDNs are the natural first line against DDoS.
The core insight

A CDN turns "where is the data?" into a question the naming and routing systems answer per-client, so that most requests are satisfied by a nearby cache instead of a distant origin.

The idea

A Content Delivery Network is a distributed system of servers, positioned at many network locations, that stores replicas of an origin's content and serves client requests from the replica expected to be fastest, cheapest, or most reliable to reach. The core resource is a set of edge servers organized into points of presence (PoPs), each holding a partial, dynamically maintained copy of the origin's data. The system's job is replica placement (deciding what content lives where) and request routing / server selection (deciding, for each client request, which replica should answer it). Two architectural patterns dominate. In a pull (reactive) CDN, edge servers start empty; on a cache miss they fetch the object from the origin (or a parent cache) and store it with a time-to-live, serving subsequent requests locally until eviction or expiry — this is the model used by general-purpose web CDNs. In a push (proactive) CDN, the origin explicitly distributes content to edges ahead of demand, typical for video-on-demand catalogs or software release artifacts where access patterns are predictable. Most production CDNs are hybrids: popular, predictable content is pushed or pre-warmed; the long tail is pulled on demand. Server selection — telling a client which edge to use — is solved chiefly by two mechanisms layered on infrastructure the client already trusts: DNS-based redirection, where the CDN's authoritative name servers return different edge IP addresses depending on which resolver asked (a technique built directly on DNS: The Internet Naming System), and anycast routing, where many edge servers share one IP address and BGP naturally routes each packet to the topologically nearest instance. A third mechanism, HTTP redirection or request routing at the application layer, lets an edge server that received a request (e.g., via anycast) issue a 302 redirect or internally proxy to a better-suited edge, refining a coarse first hop.

How it works

Step 1 — Content ingestion and placement. The origin (or CDN control plane) decides which objects are candidates for replication and which PoPs should hold them. This is driven by a cost model that trades off storage at each PoP, bandwidth to fill/refresh caches, and expected latency reduction for demand originating near that PoP.

Step 2 — DNS-based direction to a PoP. When a client resolves `www.example.com`, the origin's DNS delegates the CDN's hostname (`cdn.example.com`, often via a CNAME) to the CDN's own authoritative DNS. That authoritative server, upon seeing the query arrive from a particular recursive resolver, treats the resolver's IP (or, with EDNS Client Subnet, the client's approximate subnet) as a location hint and returns the IP address of a nearby, healthy, non-overloaded edge cluster.

Step 3 — Anycast (alternative/complementary path). Many CDNs additionally advertise the same IP prefix from every PoP via BGP. Routers along the path forward packets toward whichever PoP is topologically closest according to normal Internet routing — no per-client decision by the CDN is needed; the routing fabric itself performs the selection.

Step 4 — Request arrives at an edge server. The edge checks its local cache. On a hit, it serves the object directly (fastest path). On a miss, it may: (a) fetch from a regional/mid-tier cache (a shared parent serving a whole metro area or country), (b) fetch from the origin directly, or (c) proxy to a better edge if it discovers, via internal signaling, that a sibling holds the object.

Step 5 — Cache population and eviction. The fetched object is stored with metadata (TTL, `ETag`, `Cache-Control` directives from HTTP). Subsequent requests within the TTL are served locally. When storage fills, an eviction policy (commonly LRU, or frequency-aware variants) removes the least useful objects.

Step 6 — Health and load feedback. PoP health, load, and link congestion feed back into the DNS/routing layer continuously, so a client mid-session (or a fresh client moments later) is steered away from an overloaded or down PoP. ```pseudocode // ---- DNS-based CDN redirection (authoritative server logic) ---- function RESOLVE(query, resolverIP): clientLocation = ESTIMATE_LOCATION(resolverIP) // geo-IP or EDNS Client Subnet candidates = POPS_SERVING(query.hostname) // PoPs hosting this customer's content candidates = FILTER_HEALTHY(candidates) // drop PoPs failing health checks if candidates is empty: return ORIGIN_IP // fail open to origin best = argmin_{p in candidates} COST(p, clientLocation) return best.publicIP function COST(pop, clientLocation): // weighted combination; weights tuned by the operator return w1 NETWORK_LATENCY_ESTIMATE(pop, clientLocation) + w2 CURRENT_LOAD(pop) + w3 (1 if pop.linkCongested else 0) PENALTY // ---- Edge server request handling (pull CDN) ---- function HANDLE_REQUEST(req, edge): key = CACHE_KEY(req.url, req.headers) // vary-aware key entry = edge.cache.LOOKUP(key) if entry != null and NOT_EXPIRED(entry): edge.cache.TOUCH(key) // update recency for LRU return entry.response // cache HIT // cache MISS: fetch through the hierarchy parent = NEAREST_PARENT_CACHE(edge) response = null if parent != null: response = FETCH(parent, req) // may itself hit/miss recursively if response == null or response.status >= 500: response = FETCH(ORIGIN, req) // fall through to origin if IS_CACHEABLE(response): // honors Cache-Control, status code STORE(edge.cache, key, response, TTL(response)) if edge.cache.SIZE() > edge.cache.CAPACITY: EVICT(edge.cache) // e.g., LRU return response function EVICT(cache): victim = cache.LEAST_RECENTLY_USED() cache.REMOVE(victim) ```

Figure
CDN request path: DNS redirection then cache-hierarchy lookup
Client Recursive Resolver CDN Authoritative DNS (selects PoP) Edge PoP A (nearby, HIT) Edge PoP B (alternate) Regional Mid-tier Cache Origin Server (data center) 1. query hostname 2. forward query 3. return PoP A IP 4. HTTP request to Edge PoP A 5a. miss → 5b. miss →

Complexity & correctness

Redirection cost. DNS-based server selection adds at most one extra DNS round trip compared to resolving the origin directly, since the CDN's authoritative answer is returned in the same recursive-resolution chain: O(1)O(1) additional lookups, amortized further because resolvers cache the answer for the record's TTL. Anycast adds zero extra round trips — routing convergence happens once, at BGP timescales, not per request.

Cache lookup. Using a hash table keyed by URL (and `Vary` headers), lookup, insertion, and LRU-touch are each O(1)O(1) expected time; eviction with a doubly linked list + hash map (classic LRU) is O(1)O(1) per operation. Space is O(C)O(C) where CC is edge cache capacity in objects/bytes, independent of total catalog size — this is the whole point: an edge need not store everything, only what is locally popular.

Why caching close to users reduces latency — a simple bound. Let docd_{oc} be the round-trip time from client to origin and decd_{ec} from client to nearest edge, with dec≪docd_{ec} \ll d_{oc} by construction (edges are provisioned in many metros; the origin is in one or few). On a cache hit, response time is ≈dec+S\approx d_{ec} + S where SS is service time; on a miss served through an edge that must still fetch from origin, response time is ≈dec+deo+S\approx d_{ec} + d_{eo} + S, which is still no worse than direct origin access when dec+deo≤docd_{ec} + d_{eo} \le d_{oc} — true whenever the edge–origin path is at least partly shared or better peered than the raw client–origin path, which CDN backbone design guarantees. Expected latency is

E[latency]=p⋅(dec+S)+(1−p)⋅(dec+deo+S)E[\text{latency}] = p \cdot (d_{ec} + S) + (1-p)\cdot(d_{ec} + d_{eo} + S)

where pp is the cache hit ratio. As p→1p \to 1, latency →dec+S≪doc+S\to d_{ec} + S \ll d_{oc} + S. This is why maximizing hit ratio (via good placement, sizing, and TTL policy) is the central performance lever, not merely "add more PoPs."

Replica placement as facility location. Choosing which of kk candidate PoPs should host a replica, to minimize expected weighted latency across demand points, is an instance of the k-median / facility location problem, known to be NP-hard in general. CDNs solve it in practice with:

  • greedy/heuristic placement based on observed demand and cost gradients (place where marginal latency reduction per byte replicated is highest),
  • LFU/LRU-driven organic caching (letting the pull model discover popularity locally, an approximation to the offline optimum with no coordination overhead),
  • hierarchical caching (regional tiers absorb misses so no single edge needs the full catalog, trading one extra hop for large storage savings).

No CDN claims global optimality; the guarantee offered is closer to "no worse than direct origin fetch, usually far better," backed by continuous monitoring rather than a static proof.

Correctness of DNS-based redirection — an invariant. The essential invariant a CDN's authoritative DNS must preserve is: every IP address returned must currently be serving valid content for the requested hostname, and be reachable/healthy at return time. Health checks and short TTLs on CDN records (often 20–300 seconds, far shorter than typical DNS TTLs) let the system maintain this invariant despite PoP failures, because a stale answer is only usable for a bounded window before resolvers must re-query.

A known imprecision, honestly stated. DNS-based selection uses the resolver's address as a proxy for the client's location. When a client uses a distant public resolver (rather than its ISP's local one), this proxy is wrong, and the CDN may direct the client to a suboptimal PoP — a real, measured problem in production networks. EDNS Client Subnet (ECS) mitigates this by letting the resolver forward a client subnet hint, at some cost to resolver-side caching efficiency (answers become less shareable across clients) and privacy.

Worked example

A client in Mumbai requests `https://cdn.news-example.com/photo/breaking.jpg`. Assume three CDN PoPs: Mumbai (M), Singapore (S), and Frankfurt (F), and an origin in Virginia (O). Round-trip times from the client:

PathRTT (ms)
Client ↔ PoP M8
Client ↔ PoP S45
Client ↔ PoP F180
Client ↔ Origin O230
PoP M ↔ Origin O (backbone)190

Trace of events:

StepActorActionResult
1ClientResolves `cdn.news-example.com` via local ISP resolver in MumbaiQuery reaches CDN authoritative DNS
2CDN Auth DNSSees resolver IP in Mumbai ASN; candidates {M, S, F} all healthyChooses M (lowest `COST`, since dec=8d_{ec}=8 ms dominates)
3ClientOpens TCP/TLS to PoP M's IP, sends GETRequest key = `/photo/breaking.jpg`
4PoP MCache lookup: `breaking.jpg` not present (first requester in region)Cache MISS
5PoP MChecks its configured mid-tier parent: Singapore regional cacheRegional cache also MISS (first request globally in Asia-Pacific tier)
6Regional (Singapore)Fetches from Origin ORTT ≈ 45+... (S↔O backbone, not shown, say 160 ms) — object fetched, cached at S
7PoP MReceives object from S, stores locally with TTL = 300 s from `Cache-Control: max-age=300`Client's total latency ≈ 8 + (M↔S backbone ≈ 60) + 160 ≈ 228 ms (comparable to going direct to origin, but only for this first unlucky requester)
8Client 2 (Mumbai, 5 s later)Same GET requestPoP M cache HIT — served in ≈ 8 ms round trip, no origin/backbone traversal
910,000th client (Mumbai, within TTL window)Same GET requestStill a HIT at PoP M — origin sees exactly one request total for this object from the entire Mumbai/Singapore region during the TTL

This trace shows the essential asymmetry a CDN exploits: the first request per region pays a hierarchy-traversal cost close to (or briefly exceeding) direct-origin latency, but every subsequent request within the TTL — potentially millions — pays only the local edge RTT. The hit ratio pp from the complexity section, for a viral photo, rapidly approaches 1, and the amortized average latency across all requesters collapses toward dec+S≈8–15d_{ec} + S \approx 8\text{–}15 ms instead of 230 ms.

Common pitfalls & traps

PitfallWhy it happensConsequence
Trusting resolver IP as exact client locationPublic/third-party resolvers (e.g., large public DNS services) are not near the clientClient redirected to a distant PoP despite a nearby one existing
Overly long TTLs on dynamic contentOperator copies static-asset TTL settings onto personalized/API responsesStale or wrong (even user-A's-data-to-user-B) content served from cache
Ignoring `Vary` header in cache keyCache key built from URL onlyCompressed vs. uncompressed, or mobile vs. desktop, responses collide in one cache slot
Thundering herd on cache expiryMany clients request a hot object at the exact TTL expiry instantSimultaneous stampede of misses to origin/parent, spiking origin load momentarily
Assuming anycast always picks the "closest" PoPAnycast follows BGP path metrics, not physical distanceTraffic can be routed to a farther but "cheaper-by-policy" PoP; occasional flapping mid-session
Caching responses with authorization-sensitive headersNaive edge configuration caches any 200 OKPrivate data leaks across users sharing an edge cache

Pioneers & history

The CDN concept grew directly out of the 1990s realization that the web's centralized origin model would not scale to mass audiences — a problem crystallized by the 1994 "Slashdot effect" and repeated outages of popular sites under sudden load. The founding commercial CDN, launched from MIT research on distributed hashing and consistent hashing for content placement, showed that algorithmic replica placement (not just brute-force server duplication) was the key to scaling the web.

Origins · 1 minTom Leighton and how this was discovered
TL
Tom Leighton
1956–present · MIT applied mathematician; co-founder of a pioneering commercial CDN, applying consistent hashing and algorithmic network theory to global content distribution

DL
Daniel Lewin
1970–2001 · MIT graduate student whose thesis on consistent hashing and load balancing became the algorithmic foundation for large-scale CDN replica placement

History
1998–1999
MIT research on consistent hashing for web content distribution leads to the first large-scale commercial CDN.
2000
s: DNS-based redirection and edge caching become standard for static web assets, images, and software downloads.
2007–2012
Video streaming (progressive download, then adaptive bitrate) drives massive CDN capacity growth and push-model pre-positioning.
2010
s: Anycast-based CDN architectures scale to handle both performance delivery and volumetric DDoS absorption at the edge.
2015
–present: CDNs converge with edge computing (running application logic at PoPs) and become a standard layer of web application security.

Where this matters

Virtually every large web property — news, e-commerce, social media, software distribution, and streaming video — relies on a CDN layer between users and origin infrastructure. Video-on-demand and live streaming services depend on CDN edge caching to deliver adaptive-bitrate segments without saturating a single data center's egress. Software and OS updates (patches, container images, app-store downloads) are pushed through CDN networks to avoid overwhelming vendor origins during synchronized global release windows. API gateways and even dynamic, personalized content increasingly sit behind CDN edge compute platforms that run short application logic (routing, authentication, A/B testing) at the PoP itself, shrinking round trips further. Because CDN edges already absorb enormous, bursty legitimate traffic, they are naturally positioned to absorb illegitimate traffic too: the same distributed capacity, health-check-driven routing, and anycast fan-out that smooths a viral traffic spike also dilutes and filters a volumetric denial-of-service flood before it ever reaches the origin. This dual role — performance delivery and traffic-absorbing perimeter — is why CDNs are the natural staging ground for the mitigation techniques covered in DDoS Attacks and Mitigation.

Ask the tutor: How would you design a cache-invalidation strategy for a CDN serving a news site where articles can be corrected minutes after publication?

Why don't CDNs just replicate everything to every edge server?

Storage and bandwidth at each edge PoP are finite and costly, while the origin's full catalog can be enormous (every product image, every video, every article ever published). Replicating everything everywhere wastes capacity on objects rarely requested in a given region — a video popular in Brazil may never be requested from a PoP in Finland. Instead, CDNs let demand drive replication: pull-model caching stores an object at an edge only after that edge has actually seen a request for it, an organic approximation to the true regional popularity distribution. Push-model pre-positioning is used selectively, for content known in advance to be globally hot (a major software release, a live sporting event), where paying the replication cost upfront avoids first-request latency for millions of simultaneous viewers.

How is CDN caching different from browser caching?

Browser caching stores a copy on a single user's device, using the same HTTP cache-control semantics, but it only benefits that one user's future requests. CDN edge caching stores a shared copy serving many users behind one PoP, so a single cache-fill event benefits every subsequent nearby request, not just one browser. The two layers compose: a response can be marked `public, max-age=60` so both the CDN edge and the browser cache it, or `private, no-store` so only sensitive personal data stays out of the shared CDN tier and, if cached at all, only in the browser. Understanding HTTP cache-control headers, introduced alongside HTTP and the Web, is essential to configuring both layers correctly and avoiding data leaks across users.

What is the difference between DNS-based redirection and anycast for CDN server selection?

DNS-based redirection makes the decision at name-resolution time: the CDN's authoritative DNS server inspects the querying resolver and returns a specific edge IP address chosen for that client population. Anycast makes the decision at the routing layer: many PoPs advertise the identical IP address via BGP, and ordinary Internet routing delivers each packet to whichever advertising PoP is topologically nearest, with no CDN-side decision logic involved per request. DNS-based selection can incorporate rich application-level signals (load, health, business rules) but only refreshes as often as TTLs allow and can be misled by resolver-location mismatches. Anycast reacts instantly to routing changes and needs no DNS trust, but offers coarser, routing-determined control and can occasionally route mid-session traffic to a different PoP if BGP paths shift.

Can a CDN serve dynamic, personalized content, or only static files?

Modern CDNs serve both, but the mechanisms differ sharply. Static content (images, videos, stylesheets, software binaries) is genuinely identical for all users, so it caches trivially with long TTLs and high hit ratios. Dynamic or personalized content (a shopping cart, a logged-in dashboard) either cannot be cached at all (marked `private, no-store`) or requires edge compute — small units of application logic executing at the PoP itself to assemble a per-user response, sometimes combining a cached shell with a small personalized fragment fetched from origin. This edge-compute pattern lets a CDN accelerate even highly dynamic sites, though it never eliminates all origin traffic for genuinely unique, per-request data.

Why do CDNs matter for security, not just performance?

Any infrastructure that absorbs enormous, geographically distributed traffic volumes for legitimate performance reasons is simultaneously well-positioned to absorb illegitimate traffic. A CDN's edge fleet, health-checking, and anycast fan-out mean a volumetric flood aimed at a single IP is instead spread across dozens or hundreds of PoPs worldwide, each able to apply rate limiting and filtering locally before forwarding only clean, legitimate traffic toward the origin. This makes the CDN edge layer a natural chokepoint for detecting anomalous request patterns, an architectural theme developed further under DDoS Attacks and Mitigation.

What determines whether a CDN chooses a pull or push model for a given piece of content?

The decision hinges on predictability of demand and tolerance for first-request latency. Content whose popularity cannot be predicted in advance (a random blog post, a user-uploaded image) is best handled by pull caching, since pre-positioning it everywhere would waste storage on objects nobody requests. Content whose demand is predictable and simultaneous — a scheduled software release, a live-streamed global event, a pre-announced video premiere — benefits from push pre-positioning, because paying the replication cost before the traffic spike avoids the "first unlucky requester" penalty for millions of users hitting empty caches at once. Most production CDNs mix both strategies per content class rather than committing globally to one.

How does a CDN keep cached content from becoming stale or serving the wrong version?

Origins attach `Cache-Control` directives (`max-age`, `no-cache`, `must-revalidate`) and validators (`ETag`, `Last-Modified`) to responses, and CDN edges are contractually obligated to honor them exactly as a compliant HTTP cache would. When a TTL expires, the edge either discards the object or revalidates it with a conditional request to the origin, receiving a cheap `304 Not Modified` if nothing changed. Operators can also purge or invalidate specific cached URLs across the whole edge fleet immediately, a control-plane operation used when content must change faster than its TTL allows (a corrected article, a security patch). Getting these semantics wrong — caching content marked non-cacheable, or under-honoring purge requests — is one of the most common production incidents CDN operators guard against.

Before this