Content Delivery Networks
A Content Delivery Network (CDN) is a globally distributed set of cache servers (POPs) that store copies of your static and cacheable content close to users. Instead of every user fetching each asset from a single origin server across the world, they fetch from a nearby edge node, cutting latency from 200ms to under 20ms and shielding the origin from traffic spikes.
How it works
The problem:
Your origin server lives in us-east-1 (Virginia). A user in Sydney, Australia requests your 1.2 MB homepage bundle. The TCP handshake alone crosses the Pacific twice (~150ms RTT), then the file transfer pays for every extra round trip under slow-start. The user stares at a blank screen for 800ms while a user in Boston gets it in 60ms.
The same problem hurts your origin server. A product launch drives 100,000 requests per second for hero images. Your origin saturates its network link, your database connection pool collapses, and even Boston users now see timeouts — not because the application is slow, but because the origin is being hammered for bytes that never change.
The fix: put a cache in front of the origin, in many places, close to users. That is a CDN.
A CDN is a network of edge servers (Points of Presence, or POPs) operated by a provider like Cloudflare, Akamai, Fastly, or AWS CloudFront. Each POP runs a cache. When a user requests https://cdn.example.com/logo.png, DNS resolves to the IP of the nearest POP — not the origin. The POP checks its cache:
- Cache hit: the asset is local. Serve it immediately. ~5–20ms. Origin never sees the request.
- Cache miss: the POP fetches the asset from the origin once, stores it (keyed by URL + vary headers), and serves it. Subsequent requests are hits.
The first user in each region pays the origin fetch; everyone after them gets the cached copy until the TTL expires. For a popular asset, the cache hit ratio reaches 95–99.9%, meaning the origin sees less than 1% of real traffic.
CDN vs origin server:
| Aspect | Origin server | CDN edge |
|---|---|---|
| Location | One region (or a few) | Hundreds of POPs worldwide |
| Latency to user | 50–250ms depending on distance | 5–30ms (nearby) |
| Capacity | Bounded by your instances/servers | Provider's global capacity (huge) |
| State | Source of truth | Cache only; can be evicted |
| Failure cost | Site goes down | Edge keeps serving cached content even if origin is down |
The CDN is never the source of truth. It is a read cache. Writes always go to the origin. If the origin is down, the CDN can keep serving stale content (with stale-while-revalidate) for hours — a powerful resilience property.
TTL, invalidation, and cache hit ratio:
Every cached object has a TTL (time to live), set via the Cache-Control: max-age=N HTTP header. The edge serves the cached copy until the TTL expires, then re-fetches.
TTL is a trade-off:
- Long TTL (hours/days): high hit ratio, low origin load, but users see stale content after a deploy.
- Short TTL (seconds/minutes): fresher content, but lower hit ratio and more origin load.
For hashed, content-addressed assets like app.4f3a9b.js (filename changes when content changes), use a 1-year TTL — the file is immutable. For HTML, use a short TTL or no-cache so deploys appear quickly.
Invalidation is how you push a new version before the TTL expires. Two flavors:
- Purge: actively tell each POP to evict an object. Cloudflare, Fastly, and CloudFront all expose purge APIs. Propagates in seconds to minutes.
- Versioned URLs: change the URL instead of the content (
/app.v2.js). The old URL keeps its TTL forever; the new URL is fetched fresh. No purge needed. This is why modern build tools hash filenames.
Cache hit ratio is the percentage of requests served from the edge. 95%+ is good. Below 80% means you are paying origin egress for content the CDN could have cached. Tune TTLs, add s-maxage for shared caches, and check that your Vary header isn't fragmenting the cache unnecessarily.
When 200 POPs all cache-miss the same new asset at once, they generate 200 simultaneous origin requests — a 'thundering herd'. An origin shield is a single intermediate cache (often the CDN's regional tier) that all POPs fetch through. The origin sees exactly 1 request, no matter how many POPs miss. Configure a short shield TTL (e.g., 1 minute) so the herd collapses into a single fetch.
Your site uses hashed filenames like `app.4f3a9b.js`. What Cache-Control header should you use for these?
Pick one answer.
You deployed a CSS fix but users still see the old styles 10 minutes later. The file is `styles.css` with `Cache-Control: max-age=3600`. What is the cleanest fix going forward?
Pick one answer.
Your origin goes down entirely for 30 minutes. Users can still load the homepage. How?
Pick one answer.
Engineering mental model
Mental model. Think of Content Delivery Networks as a deliberate boundary in a system. The boundary exists because something becomes harder to manage when everything is done in one place: latency, scale, failure isolation, consistency, cost, or team ownership. The useful question is not “what does Content Delivery Networks mean?” but “what pressure makes this boundary worth introducing, and what new failure mode does it create?”
Before choosing Content Delivery Networks, name the workload, the critical user path, the dominant bottleneck, the failure you are trying to absorb, and the trade-off you are willing to accept. If you cannot name those five things, the design is probably premature.
// Pseudocode
request = receive()
result = cdn(request)
return result
// Production questions:
// 1. What happens on timeout?
// 2. Can this operation be retried safely?
// 3. What is the bottleneck?Back-of-the-envelope reasoning
Numerical lens: write down traffic, payload size, read/write ratio, peak multiplier and durability target before choosing a component. The numbers should justify the architecture.
Interactive thought experiment: Content Delivery Networks
Change the variables below and predict what breaks first in Content Delivery Networks. The production lab can later reuse these same inputs.
Change one variable at a time. Predict the failure mode first, then move the slider and see whether your mental model matches the simplified system response.
If you are stuck on Content Delivery Networks, start by drawing the request path and marking every network hop, stateful component, queue, cache and failure boundary. Then estimate where the system will saturate.
You increase traffic by 10× in a system using Content Delivery Networks. What should you inspect first?
Pick one answer.
Which statement is the safest engineering habit when using Content Delivery Networks?
Pick one answer.
You have dashboards for traffic, latency, errors and saturation. You can change the architecture, but every change has operational cost.
Production scenario: your system uses Content Delivery Networks, traffic suddenly spikes, and p99 latency doubles. What is your first move?
Interview drill
Answer this without notes: When would you choose Content Delivery Networks, and when would you intentionally avoid it? Mention at least one bottleneck it addresses, one failure mode it introduces, and one alternative. Then quantify the workload you are designing for.
A useful engineering lens for Content Delivery Networks: define the problem it solves, the simpler design that fails first, the constraint that forces you to introduce this concept, and the new failure modes the concept creates.
Numerical sanity check
Back-of-the-envelope reasoning beats fake precision. State your traffic, payload, concurrency and growth assumptions explicitly, then calculate enough to know whether the current architecture is orders of magnitude away from the target.
Do not optimize for a memorized definition. Reason from the workload and failure mode.
Imagine the simplest version of a system using Content Delivery Networks. What breaks first as traffic grows by 10×, and what would you change before reaching 100×?
Pick one answer.
What you gain, what you pay
- +Cuts latency dramatically: 5–30ms from the edge instead of 50–250ms from a distant origin.
- +Shields the origin from traffic spikes — viral content is absorbed at the edge.
- +Origin decoupling: cached content keeps serving even if the origin is down.
- +Often cheaper than origin egress: CDN egress to users is frequently priced lower than cloud-origin egress.
- +Built-in DDoS absorption and WAF at the edge (provider-dependent).
- −Adds another moving part and a vendor relationship.
- −Cache invalidation is hard; stale content bugs are common and confusing.
- −Dynamic, per-user content (personalized HTML, API responses) is hard to cache correctly.
- −Hit ratio below ~80% means you're paying for the CDN AND paying origin egress.
- −CDN itself is a dependency — a global CDN outage takes down your static assets too.
How this breaks in production
- Stale content served after a deploy because the TTL is too long and no purge was issued.
- Cache key fragmentation: a `Vary: Cookie` or `Vary: User-Agent` header causes the CDN to cache hundreds of near-identical copies, destroying hit ratio.
- Thundering herd on origin when a popular asset expires simultaneously across many POPs (mitigate with origin shield).
- CDN provider outage — your static assets go down globally even though your origin is healthy.
- Caching personalized responses by accident, leaking one user's data to another. Never cache responses that depend on auth headers without explicit cache key design.
Don't fall into these traps
- •Setting a long TTL on HTML or API responses, then complaining that deploys don't propagate.
- •Using query strings for cache busting without confirming the CDN includes them in the cache key.
- •Forgetting `s-maxage` — the browser `max-age` doesn't control CDN caches; `s-maxage` does.
- •Treating CDN as a black box. If hit ratio is bad, you are paying for nothing. Monitor it.
- •Caching POST responses or responses with auth-derived content. CDNs cache GETs by default; never enable caching on endpoints that return user-specific data without careful key design.
Real systems using this
How real systems implement this
- Cloudflare — Operates 300+ POPs globally. Serves static assets, provides a WAF, and offers Workers for compute at the edge (CDN + serverless in one platform). Cache purge API propagates in seconds.
- Netflix Open Connect — Netflix runs its own purpose-built CDN with appliances placed inside ISPs' networks (OCA — Open Connect Appliances). Video is pre-populated onto OCAs overnight, so streaming rarely touches Netflix's origin.
- AWS CloudFront — Managed CDN integrated with S3 and other AWS origins. Supports origin shield, field-level encryption, signed URLs for private content, and Lambda@Edge for request/response manipulation at the edge.
Practice saying it out loud
- Q1Design a global image-hosting service. Where does the CDN fit, and how do you handle cache invalidation when a user replaces an image?
- Q2Your CDN hit ratio dropped from 95% to 70% overnight. How do you debug it?
- Q3Explain the difference between browser caching (max-age) and CDN caching (s-maxage). Why does it matter?
- Q4Your origin is down. Users can still load cached pages. How would you extend this 'serve stale' behavior to API responses safely?
- Q5A viral product launch is tomorrow. How do you pre-warm the CDN so the origin doesn't get crushed at launch?
Further reading & references
Core explanations are original NO CAP material. External references are provided for deeper study and standards.
What next?
Mark as understood once the mental model clicks.
Next recommended
Caching Strategies