System DesignBeginner 12 min Lesson 9 of 42

CDN — Serving From Nearby

Why distance costs milliseconds, how edge caching removes most of your traffic, and how to avoid serving stale content.

System Design · Lesson 9 of 42
0/42 done(0%)

What is it? #

A CDN is a network of servers spread around the world that hold copies of your content and serve it from wherever the user is.

Two things improve. Distance: light takes real time to travel, and a request crossing continents costs hundreds of milliseconds before any work is done. Load: content served from the edge never reaches your servers at all.

It is most effective for static files — images, scripts, stylesheets, fonts, video — but modern CDNs also cache API responses and whole pages when you tell them it is safe.

The hard part is not enabling it. It is deciding what may be cached, for how long, and how to update it when content changes.

Think of it like this #

A chain of local warehouses instead of one central depot. Popular items are stocked nearby, so most orders ship from a few kilometres away rather than across the country.

The central depot still holds everything and restocks the warehouses. Nobody waits for a long-distance delivery unless the item is unusual.

Simple example #

Your server is in Mumbai and a user in Berlin loads a page with thirty assets. Without a CDN, every asset makes the round trip. With one, they come from a European edge in a few milliseconds, and your server sees only the initial page request.

Code #

TEXT
Without a CDN                    With a CDN

Berlin user                      Berlin user
    │  ~250ms round trip             │  ~15ms
    ▼                                ▼
Mumbai server (all 30 assets)    Frankfurt edge (cached assets)
                                     │  only on a cache miss
                                     ▼
                                 Mumbai origin server
TEXT
Cache headers that control CDN behaviour

Cache-Control: public, max-age=31536000, immutable
    versioned assets — app.a1b2c3.js — cache for a year, never revalidate

Cache-Control: public, max-age=300, stale-while-revalidate=86400
    a page that may change — serve cached for 5 minutes, then refresh in
    the background while still serving the old copy

Cache-Control: private, no-store
    user-specific or sensitive — never cache anywhere

Vary: Accept-Encoding, Accept-Language
    cache separate copies per encoding and language
BASH
# Is this response coming from the edge?
curl -sI https://example.com/static/app.a1b2c3.js | grep -Ei "cache|age|x-cache"

# X-Cache: HIT  served from the edge
# X-Cache: MISS fetched from your origin and now cached
# Age: 412      seconds since it was cached
TEXT
Versioned filenames beat invalidation

BAD   /static/app.js  with a long cache time
      → changing it requires a purge, and old copies linger

GOOD  /static/app.a1b2c3.js  with a one-year cache time
      → a new build produces a new filename, so there is nothing to purge

How it works #

A CDN edge receives the request. If it holds a fresh copy, it returns it immediately — that is a cache hit, and your server is never contacted.

On a miss, the edge fetches from your origin server, stores the response according to its cache headers, and serves it. The next user in that region gets a hit.

The cache key is usually the URL plus whatever the Vary header lists. Two URLs differing by a query parameter are separate entries, which is why tracking parameters can quietly destroy your hit rate.

immutable tells the browser and edge not even to revalidate. It is safe only when the filename changes whenever the content does, which is exactly what build-time hashing provides.

stale-while-revalidate is the most useful directive for semi-dynamic content. Users always get an instant response, and the refresh happens in the background.

Purging is the escape hatch, and it is slower and less reliable than versioning. The versioned filename approach in the last block avoids the problem entirely: new content has a new URL, so there is no stale copy to chase.

Anything user-specific must be marked private, no-store. Caching a logged-in page at a shared edge and serving it to another user is a real and serious incident.

Real-world use #

Every significant site uses a CDN. Cloudflare, Fastly, CloudFront and others offer it, and static hosting platforms include it by default.

Beyond speed, CDNs absorb traffic spikes and denial-of-service attacks, because the edge takes the load rather than your origin. That protective role is often the main reason to use one.

Edge computing extends this further, running small pieces of logic at the edge — redirects, authentication checks, personalisation — without a round trip to origin.

The most common practical problems are stale content after a deploy, caching a personalised page by accident, and low hit rates caused by query parameters or overly specific Vary headers. Checking X-Cache and Age headers is the quickest way to diagnose all three.

Common mistakes #

  • Caching pages that contain user-specific data at a shared edge.
  • Using unversioned filenames with long cache times, then fighting stale copies.
  • Letting tracking query parameters fragment the cache key and destroy the hit rate.
  • Setting Vary on headers that differ per user, making every response unique.
  • Assuming a CDN fixes a slow origin. Cache misses still hit your server.

Practice #

Take a page you control and list every asset. Decide the cache policy for each: versioned and immutable, short with revalidation, or never cached. Then use curl -sI on a CDN-served asset and identify whether it was a hit, and how old the cached copy is.

Quick quiz

  1. 1. What is the main reason a CDN reduces latency?

  2. 2. What does `immutable` in Cache-Control mean?

  3. 3. Why are versioned filenames better than purging?

  4. 4. What does `stale-while-revalidate` do?

  5. 5. What can destroy your cache hit rate?

Summary

  • A CDN serves copies of your content from near the user.
  • Cache headers decide what is cached, for how long, and by whom.
  • Version filenames so long cache times never need purging.
  • Never cache user-specific responses at a shared edge.
  • CDNs also absorb traffic spikes and protect the origin.