← Computer Networks
Traffic Management & Resilience

CDN (Content Delivery Network)

Watch: "What is a Content Delivery Network (CDN)?" — IBM Technology

Latency is bounded by the speed of light, so no amount of backend optimization helps a user thousands of miles from your origin server — a round trip from Mumbai to a us-east origin is going to cost roughly 200ms no matter how fast your database is. A CDN caches content at geographically distributed edge locations (PoPs) so the response never has to make that trip at all. Understanding cache hit/miss behavior, not just "CDNs make things faster," is essential for any system-design discussion involving global scale.

What Is a CDN?

A CDN (Content Delivery Network) is a network of servers spread across many physical locations around the world that store copies of a website's content close to the people requesting it. Instead of every visitor's request traveling all the way to one central server, it's answered by a nearby copy, which makes the page or video load faster.

Where This Is Used

A Day-to-Day Example

Think of a popular pizza chain. Instead of baking every pizza in one central kitchen and shipping it across the country, the chain opens local branches in every neighborhood, each stocked with the same recipe and ingredients. When you order, the nearest branch makes it, so you get a hot pizza in twenty minutes instead of waiting days for one to arrive from headquarters.

Deep Dive: The Request Path — Hit vs Miss

CDN cache hit and cache missHIT: fast path, often < 20 msusernearest edge PoPhas it cachedrequestserved from cacheMISS: first request or expired TTLusernearest edge PoPcache missorigin serverfetchresponse, now cached
On a hit the user only travels to the nearby edge. On a miss the edge fetches from the origin first (distance to edge + distance to origin + origin work), keeps a copy, and every nearby user after that gets a hit.
hitmiss
Show text version
Cache HIT (common case, fast path):
  User --> Nearest Edge PoP --[cache has it]--> served directly
  Latency ~= physical distance to nearest PoP only (often <20ms)

Cache MISS (first request for an object, or expired TTL):
  User --> Nearest Edge PoP --[miss]--> Origin Server
                              <--response--
        edge CACHES the response, then --> serves User
  Latency = distance-to-edge + distance-to-origin + origin processing
  Subsequent nearby users then get a HIT from that same edge.

The core interview insight: a CDN's value compounds — the first user in a region "pays" the miss cost and warms the cache; every user after them in that region gets the hit-path latency until the TTL expires. This is also why a cold, rarely-requested object (the "long tail") gets little CDN benefit — it's effectively always a miss.

Deep Dive: Origin Pull vs Origin Push, and Shield Caching

Key Pointers

How It Works

  1. Client resolves the CDN-fronted domain via DNS (or anycast), which routes it to an edge PoP close to the client.
  2. The request hits the edge node, which checks its cache for the resource.
  3. On a cache hit, the edge serves the cached response immediately — this is the goal state for most traffic.
  4. On a cache miss, the edge pulls from the origin (or a mid-tier "shield" cache), stores it per the resource's TTL/cache-control headers, then serves it.
  5. Subsequent requests for the same resource from nearby users are served from cache until TTL expiry or explicit invalidation/purge.

Try It Yourself

# Check whether a response was a CDN hit or miss — look for
# X-Cache, CF-Cache-Status, Age, or similar headers
curl -sI https://example.com/static/logo.png | grep -i "cache\|age\|x-served"

# Compare timing for a cached static asset vs an uncached/dynamic
# endpoint using curl's timing breakdown
curl -w "@curl-format.txt" -o /dev/null -s https://example.com/static/app.js
curl -w "@curl-format.txt" -o /dev/null -s https://example.com/api/data
# curl-format.txt contents:
#   time_namelookup:  %{time_namelookup}\n
#   time_connect:     %{time_connect}\n
#   time_starttransfer: %{time_starttransfer}\n
#   time_total:       %{time_total}\n

# Request the same resource twice in a row — second request should
# show a HIT and a much lower time_starttransfer
curl -sI https://example.com/static/app.js | grep -i x-cache
curl -sI https://example.com/static/app.js | grep -i x-cache

# Inspect actual cache-control policy being sent by origin/edge
curl -sI https://example.com/ | grep -i "cache-control\|expires\|vary"

Interview Q&A

Q: Walk me through what happens on a cache miss for a brand-new object.

A: The request reaches the nearest edge PoP, the edge checks its local cache, finds nothing (miss), and forwards the request upstream — either directly to origin or through a shield tier if one exists. The origin generates the response, the edge stores it according to the response's cache-control/TTL headers, and finally serves it to the requesting user. Every subsequent request for that same object from users near that edge is now served as a hit until the TTL expires or it's explicitly purged.

Q: How do you avoid stale content being served after you deploy a fix?

A: Either set short TTLs for content that changes often, use cache-busting via versioned/fingerprinted URLs (e.g. app.a1b2c3.js) so a new deploy is automatically a new cache key, or issue an explicit purge/invalidation call to the CDN provider's API. Versioned filenames are generally preferred over purging because purges have propagation delay across thousands of edge nodes and can be rate-limited by the provider.

Q: Can you cache API responses, and what makes that safe or unsafe?

A: Yes, when the response is not personalized (or personalization is captured correctly via a Vary header, e.g. varying on an auth token or locale) and a bounded staleness window is acceptable. Unsafe caching usually comes from forgetting to vary on something that affects the response — caching a personalized response as if it were shared would leak one user's data to another.

System Design Tie-in

In "design a system serving global users" questions (video platform, image-heavy social feed, e-commerce catalog), the CDN is the first layer you should mention for anything static or infrequently-changing — it removes both latency and load from every other component in the design. It also comes up directly when asked "how would you handle a traffic spike" (edge absorption) or "how would you defend against a DDoS attack" (volumetric traffic dies at the edge rather than reaching origin capacity). When a design includes user-generated content or personalization, expect a follow-up on how you'd decide what's cacheable vs what must hit origin — that's exactly the shield-caching / cache-key discussion above.

Trade-offs

CDNs cut latency and origin load dramatically but introduce cache-invalidation complexity — stale content, purge propagation delay across thousands of PoPs, and correctness risk for personalized or rapidly changing responses. Interview gotcha: know the cache-control directives (max-age, no-store, stale-while-revalidate) and how tiered/shield caching reduces origin fan-out when many edge nodes miss on the same cold object at once — this is the difference between "the CDN helps" and "the CDN survives a launch-day traffic spike."