System Design: Content Delivery Network (CDN) — Cache, Routing, Edge

System Design: Content Delivery Network (CDN)

A CDN is a geographically distributed network of edge servers that caches and serves content close to users. It reduces latency from hundreds of milliseconds (cross-continental origin requests) to single-digit milliseconds (nearby edge), while offloading 80-95% of traffic from origin servers.

Core Components

  • Edge PoPs (Points of Presence): servers in ~200+ global locations that cache and serve content
  • Origin: source of truth — your web servers, S3 buckets, or API servers
  • DNS Anycast: routes user DNS queries to the nearest PoP IP
  • Cache Tier: L1 (edge memory), L2 (edge SSD), L3 (regional shield) before hitting origin

Request Routing: How a User Reaches the Nearest Edge


User types example.com
  → ISP resolver queries → CDN authoritative DNS
  → DNS returns Anycast IP (routes to nearest PoP via BGP)
  → User TLS handshake with edge server (30ms vs 200ms to origin)
  → Edge: cache HIT → serve response (5ms)
  → Edge: cache MISS → fetch from origin, cache, serve (150ms first time)

Cache Key Design

The cache key determines whether two requests share a cache entry. Default: URL (scheme + host + path + query). Vary by:

  • Accept-Encoding: serve gzip to Chrome, brotli to Firefox
  • Accept-Language: if content is localized
  • Never vary on Cookie for public content — destroys cache hit rate
  • Strip tracking parameters (utm_source, fbclid) from cache keys to consolidate variants

Cache Invalidation Strategies


# Strategy 1: TTL-based (simplest)
# Origin sets Cache-Control: public, max-age=3600
# Edge serves stale content up to 1 hour; no invalidation mechanism

# Strategy 2: Versioned URLs (best for static assets)
# /static/app.js?v=a1b2c3d4  — hash of file contents
# New deploy → new hash → new cache key → instant propagation
# Old URLs cached until TTL; safe because content is identical

# Strategy 3: CDN Purge API (for mutable content)
import requests

def purge_cdn_url(url: str, cdn_api_key: str) -> bool:
    """Cloudflare Cache Purge API example."""
    response = requests.post(
        "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache",
        headers={"Authorization": f"Bearer {cdn_api_key}"},
        json={"files": [url]},
        timeout=5,
    )
    return response.json().get("success", False)

# Strategy 4: Surrogate keys / Cache tags (advanced)
# Origin sets: Surrogate-Key: product-123 category-electronics
# Purge all URLs tagged product-123 in one API call when product changes

Cache Hit Rate Optimization

Technique Impact
Strip irrelevant query params from cache key +10-20% HIT rate
Normalize URL (lowercase, sort params) +5% HIT rate
Shield origin (regional PoP consolidates misses) Reduces origin load 10x
Prefetch popular content at PoP startup Eliminates cold start misses
Serve stale-while-revalidate Removes TTL latency spikes

Origin Shield (Tiered Caching)

Without shielding: 200 edge PoPs all independently fetch from origin on a cache miss → 200 origin requests per unique URL. With shielding: a regional “shield” PoP consolidates misses. Edge → Shield (L2 cache) → Origin. Typically 1 shield per region (US-East, EU-West, AP-South). Reduces origin requests from 200× to 3× for a global miss.

Dynamic Content and Edge Computing

Modern CDNs run code at the edge (Cloudflare Workers, Lambda@Edge) for:

  • A/B testing: split traffic at edge without origin round-trip
  • Auth token validation: reject unauthorized requests at edge, saving origin compute
  • Response transformation: image resizing, HTML minification
  • Geo-blocking: block by country before traffic reaches origin

Security Features

  • DDoS absorption: CDN edge absorbs volumetric attacks (Tbps-scale); origin only sees legitimate traffic
  • TLS termination: CDN handles TLS handshakes; origin can use HTTP internally on private network
  • WAF (Web Application Firewall): filter SQLi, XSS, rate limiting at edge
  • Bot management: fingerprinting + challenge pages at edge

Interview Framework

  1. Identify cacheable vs non-cacheable content (static assets vs user-specific API responses)
  2. Choose cache key strategy (URL only, or vary on headers)
  3. Define TTL and invalidation approach per content type
  4. Discuss origin shield for high-traffic origins
  5. Address security (DDoS, WAF) and edge compute if dynamic needs arise

{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “How does a CDN route users to the nearest edge server?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “CDNs use DNS Anycast: the CDN’s authoritative DNS server returns the same IP address globally, but BGP routing in the internet backbone steers traffic to the nearest network location advertising that IP. Alternatively, GeoDNS returns different IPs based on the querying resolver’s location. When a user’s browser resolves cdn.example.com, they receive the IP of the nearest PoP, and their TCP connection terminates there rather than at the origin server.”
}
},
{
“@type”: “Question”,
“name”: “What is origin shielding and why does it matter?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Origin shielding places a regional “shield” PoP between edge servers and the origin. Without it, a cache miss at any of 200 global edge nodes independently fetches from origin u2014 200 simultaneous origin requests for a cache cold-start. With shielding, all edge PoPs in a region route misses to one shield PoP, which makes a single request to origin and caches the response for all regional edges. This reduces origin load by ~100x for global deployments.”
}
},
{
“@type”: “Question”,
“name”: “What are surrogate keys (cache tags) and when do you use them?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Surrogate keys (Cloudflare: Cache-Tag, Fastly: Surrogate-Key) are metadata tags attached to cached responses by the origin. Example: a product page response includes header “Surrogate-Key: product-123 category-electronics”. When product-123 is updated, a single CDN purge API call invalidates all cached URLs tagged product-123 across all edge PoPs simultaneously. This is far more efficient than purging individual URLs when one entity appears on many pages (product in list, detail, related, search).”
}
},
{
“@type”: “Question”,
“name”: “How do you handle cache invalidation for mutable content on a CDN?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Three strategies: (1) Short TTL (60-300s): stale content window, no API required, simple but serves stale data. (2) Purge API: on content update, call CDN purge endpoint to evict specific URLs or surrogate keys u2014 immediate consistency, requires integration. (3) Versioned URLs: embed a content hash in the URL (/static/logo.v2a1b3c.png); new content = new URL = new cache key, zero invalidation needed u2014 best for immutable assets. Use versioned URLs for static assets, purge API for CMS pages, short TTL for API responses.”
}
},
{
“@type”: “Question”,
“name”: “What is stale-while-revalidate and how does it improve performance?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “stale-while-revalidate is a Cache-Control directive: “max-age=60, stale-while-revalidate=3600″. After the 60s TTL expires, the CDN serves the stale cached response immediately (no latency penalty) while asynchronously fetching a fresh version from origin in the background. Users never wait for a cache miss during revalidation. Without it, the first request after TTL expiry would block waiting for origin. Trade-off: users may see slightly stale content for up to stale-while-revalidate seconds.”
}
}
]
}

Asked at: Cloudflare Interview Guide

Asked at: Netflix Interview Guide

Asked at: Uber Interview Guide

Asked at: Twitter/X Interview Guide

Asked at: Shopify Interview Guide

Scroll to Top