Content Delivery Networks (CDN)
How CDNs work: edge caching, PoPs, cache invalidation, push vs pull CDNs, and when to use them in system design.
What Is a CDN?
A Content Delivery Network (CDN) is a globally distributed network of proxy servers (called edge nodes or Points of Presence, PoPs) that cache content close to end users. Instead of every request crossing the Atlantic to reach an origin server in Virginia, a user in Tokyo gets served from a PoP in Osaka — reducing round-trip time from ~200ms to ~5ms.
CDNs are used by virtually every high-traffic website. Cloudflare, Akamai, AWS CloudFront, and Fastly collectively serve a significant fraction of global internet traffic. Understanding CDNs is essential for system design interviews because they address latency, availability, and origin server load in one architectural decision.
Pull CDN vs Push CDN
CDNs operate in two fundamental modes for populating edge caches:
| Aspect | Pull CDN | Push CDN |
|---|---|---|
| How content gets to edge | Edge fetches from origin on first cache miss, then caches locally | You proactively upload content to all edge nodes |
| Setup complexity | Low — just point DNS at CDN | Higher — must push on every update |
| Best for | Dynamic sites with unpredictable access patterns | Large static assets (videos, software downloads) with known distribution |
| Storage cost | Only caches what's actually requested | Must store all content at all PoPs |
| Freshness control | TTL-based; stale content served until TTL expires | You control exactly when content is deployed |
| Examples | Cloudflare, CloudFront (default mode) | Akamai NetStorage, CloudFront with S3 push |
When to recommend a CDN in an interview
Mention CDNs whenever your design serves: static assets (JS, CSS, images), video streams, large file downloads, or any globally distributed user base. A CDN can also absorb DDoS traffic at the edge before it reaches your origin. For purely internal services (microservices calling each other), CDNs are not relevant.
Cache Control Headers
CDN behavior is controlled primarily through HTTP response headers set by your origin server. The most important are `Cache-Control` and `ETag`.
# Cache for 1 hour at CDN, but never in browser
Cache-Control: public, max-age=3600, s-maxage=3600, no-store
# Immutable asset with content-hash in filename — cache forever
Cache-Control: public, max-age=31536000, immutable
# Private user data — never cache at CDN
Cache-Control: private, no-cache, no-store
# ETag for conditional requests
ETag: "abc123def456"
Last-Modified: Wed, 19 Feb 2026 10:00:00 GMT- `Cache-Control: public` — Allows CDNs and shared caches to store the response.
- `s-maxage` — Overrides `max-age` specifically for shared caches (CDNs). Allows different TTLs for browser vs edge.
- `immutable` — Tells the browser not to revalidate the resource even after max-age expires. Used with content-addressed filenames.
- `ETag` — A fingerprint of the content. Browsers/CDNs can send `If-None-Match: <etag>` to check for updates without downloading unchanged content.
- `Vary` — Instructs CDNs to cache different versions based on request headers (e.g., `Vary: Accept-Encoding` for gzip vs br variants).
Cache Invalidation at the CDN Layer
CDN cache invalidation is one of the harder operational problems. Once content is cached at hundreds of edge nodes globally, removing stale data requires explicit purge APIs.
- TTL expiry: The simplest approach — wait for the TTL to pass. Zero operational cost but potentially serves stale content for the full TTL duration.
- URL purge / cache tag purge: Explicitly tell the CDN to evict specific URLs or tagged groups of objects via API. Cloudflare, Fastly, and CloudFront all support this.
- Cache-busting via versioned URLs: Embed a content hash in the filename (`main.a3f8c2.js`). When the file changes, the URL changes, making the old cached version irrelevant. This is the most reliable strategy for static assets.
- Surrogate keys / cache tags: Tag groups of objects (e.g., all pages showing product ID 42) and purge them atomically when the product changes. Fastly and Cloudflare support this natively.
Real-world pattern: Immutable assets + short-lived HTML
Netflix and modern web frameworks use a two-layer strategy: JavaScript/CSS bundles get content-hash filenames and a 1-year `max-age` (immutable). HTML pages that reference those bundles get a short TTL (30-60 seconds) or `no-cache`. This way, assets are served blazing-fast from edge caches indefinitely, while HTML always stays fresh.
CDN for Dynamic Content
Modern CDNs can accelerate even non-cacheable dynamic content through origin shielding (funnel cache misses through a single shield PoP to reduce origin load), protocol optimization (keeping persistent HTTP/2 or HTTP/3 connections to origin), and edge compute (running logic like auth, A/B testing, and personalization at the CDN edge via Cloudflare Workers or Lambda@Edge).
Interview Tip
A common interview follow-up: 'What if the user's data is personalized — can you still use a CDN?' The answer is yes, with nuance. You can still CDN-cache the page shell (HTML without user-specific data) and fetch personalized sections via client-side API calls that bypass the CDN. Alternatively, use edge compute to inject personalized data after the cache hit. This pattern is called 'Edge Side Includes' (ESI) or 'stale-while-revalidate with personalization at the edge'.