Why CDNs Matter
Why This Matters
The Problem: A user in Tokyo requests an image from a server in Virginia. The round trip crosses the Pacific Ocean, adding 150-200ms of latency. Multiply that by dozens of assets per page, and your site feels sluggish.
The Solution: A CDN (Content Delivery Network) caches your content at hundreds of edge locations worldwide. That Tokyo user gets the image from an edge server in Japan in under 10ms.
Real Impact: Netflix serves over 200 million hours of video daily through its Open Connect CDN, reducing bandwidth costs by over 50% and cutting latency to under 25ms for 95% of users.
Real-World Analogy
Think of a CDN like a chain of local libraries:
- Origin server = The publisher's warehouse (has every book, but far away)
- Edge servers = Local library branches (stock popular books close to readers)
- Cache hit = Book is available at your local branch (fast pickup)
- Cache miss = Branch orders from the warehouse (slower, but now stocked locally)
- TTL (Time to Live) = How long the library keeps a book before checking for a new edition
What CDNs Deliver
Lower Latency
Content served from the nearest edge location. Users experience sub-50ms load times for cached assets instead of 200ms+ from a distant origin.
Reduced Origin Load
Edge servers absorb 80-95% of traffic. Your origin handles only cache misses and dynamic requests, reducing infrastructure costs dramatically.
DDoS Protection
Distributed edge network absorbs volumetric attacks. Malicious traffic is filtered before reaching your origin servers.
Global Availability
Even if your origin goes down, cached content remains available at edge locations for the duration of the TTL.
How CDNs Work
Request Flow: Cache Hit vs Cache Miss
Push vs Pull CDN
| Aspect | Pull CDN | Push CDN |
|---|---|---|
| How it works | Edge fetches from origin on first request (lazy loading) | You upload content to CDN in advance (eager loading) |
| Setup | Configure origin URL; CDN handles the rest | You manage uploads, file paths, and invalidation |
| First request | Slow (cache miss, fetches from origin) | Fast (already cached at edge) |
| Storage cost | Lower (only caches popular content) | Higher (stores everything you push) |
| Best for | Websites with many assets, traffic-driven caching | Video streaming, large files, predictable access |
| Examples | Cloudflare, Fastly | AWS CloudFront + S3, Netflix Open Connect |
Cache Invalidation
The Hardest Problem in CS (After Naming Things)
"There are only two hard things in Computer Science: cache invalidation and naming things." -- Phil Karlton
When you update content at the origin, stale copies may persist at edge locations until the TTL expires. Getting fresh content to users quickly without overwhelming your origin is the core challenge.
Invalidation Strategies
TTL-Based Expiration
Set a Time to Live on each cached asset. After expiry, the edge re-validates with the origin. Simple but content may be stale for up to the full TTL duration.
Cache Busting (Versioned URLs)
Append a hash or version to the URL: style.a1b2c3.css. New deployment = new URL = cache miss. Most effective strategy for static assets.
Purge API
CDN providers offer APIs to instantly purge specific URLs or patterns. Use after content updates that must propagate immediately.
Stale-While-Revalidate
Serve the stale version immediately while fetching a fresh copy in the background. Users get fast responses and eventual freshness.
# Static assets: cache for 1 year (use cache busting for updates)
location ~* \.(js|css|png|jpg|svg|woff2)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
# HTML pages: revalidate every time
location ~* \.html$ {
add_header Cache-Control "no-cache";
# no-cache means "revalidate before serving" (NOT "don't cache")
}
# API responses: short TTL with stale-while-revalidate
location /api/ {
add_header Cache-Control "public, max-age=60, stale-while-revalidate=300";
# Serve cached for 60s, then serve stale for up to 5min while revalidating
}
Edge Computing
Edge computing goes beyond caching static content. It runs your code at edge locations, enabling personalization, A/B testing, authentication, and request routing without a round trip to your origin server.
Edge vs Origin Computing
- Edge functions run in under 1ms cold start on lightweight runtimes (V8 isolates, not full containers)
- Cloudflare Workers, Vercel Edge Functions, AWS Lambda@Edge are popular platforms
- Use cases: URL rewrites, A/B testing, geolocation redirects, JWT validation, bot detection
- Limitations: Limited CPU time (usually 10-50ms), restricted APIs, no persistent storage (use KV stores)
# Cloudflare Worker-style edge function (conceptual Python)
# In practice, Workers use JavaScript/Rust/WASM
async def handle_request(request):
"""Route users based on geolocation at the edge."""
country = request.headers.get('CF-IPCountry', 'US')
url = request.url
# Geo-based routing: redirect EU users to EU origin
if country in EU_COUNTRIES:
return Response.redirect(
url.replace('api.example.com', 'api-eu.example.com')
)
# A/B testing: 10% of users see variant B
user_id = request.cookies.get('user_id', '')
if hash(user_id) % 10 == 0:
response = await fetch(url, headers={'X-Variant': 'B'})
else:
response = await fetch(url)
# Add security headers at the edge
response.headers['X-Frame-Options'] = 'DENY'
response.headers['Strict-Transport-Security'] = 'max-age=31536000'
return response
CDN Selection Criteria
| Criterion | What to Evaluate | Why It Matters |
|---|---|---|
| PoP Coverage | Number and location of edge servers | More PoPs = lower latency for global audiences |
| Performance | TTFB, throughput, cache hit ratio | Directly impacts user experience and SEO rankings |
| Edge Compute | Support for edge functions, KV storage | Enables personalization without origin round-trips |
| Security | DDoS protection, WAF, bot management | Protects origin from attacks |
| Cost Model | Bandwidth pricing, request pricing, egress fees | Video and large file delivery can be expensive |
| Purge Speed | Time to invalidate cached content globally | Critical for news sites and dynamic content |
Practice Problems
Medium CDN Cache Strategy
Design a caching strategy for an e-commerce site with:
- Product images (rarely change)
- Product pages (prices update hourly)
- Shopping cart API (user-specific, real-time)
Different content types need different TTLs and caching strategies. Static images can be cached aggressively with cache busting. Dynamic, user-specific content should bypass the CDN cache.
# 1. Product images: long TTL + cache busting
Cache-Control: public, max-age=31536000, immutable
# URL: /images/product-abc123.v2.jpg
# New image = new URL, old ones naturally expire
# 2. Product pages: short TTL + stale-while-revalidate
Cache-Control: public, max-age=300, stale-while-revalidate=3600
# Fresh for 5 min, serve stale up to 1 hour while updating
# Price changes propagate within 5 minutes
# 3. Shopping cart API: bypass CDN cache
Cache-Control: private, no-store
# private = CDN won't cache (only browser can)
# no-store = don't cache at all
# Route directly to origin for real-time data
Medium Edge Function Design
Design an edge function that handles:
- Redirecting mobile users to a mobile-optimized site
- Blocking requests from sanctioned countries
- Adding CORS headers for your API endpoints
Check the User-Agent header for mobile detection. Use the geo-IP header (provided by CDNs) for country blocking. Add CORS headers to preflight and regular responses.
async def handle_request(request):
country = request.cf.country
ua = request.headers.get('User-Agent', '')
origin = request.headers.get('Origin', '')
# 1. Block sanctioned countries
BLOCKED = {'KP', 'IR', 'SY'}
if country in BLOCKED:
return Response('Access denied', status=403)
# 2. Mobile redirect
is_mobile = 'Mobile' in ua or 'Android' in ua
if is_mobile and not request.url.startswith('m.'):
return Response.redirect('https://m.example.com' + request.path)
# 3. CORS for API
response = await fetch(request)
if origin in ALLOWED_ORIGINS:
response.headers['Access-Control-Allow-Origin'] = origin
response.headers['Access-Control-Allow-Methods'] = 'GET, POST'
return response
Hard Multi-CDN Architecture
Design a multi-CDN strategy for a global video streaming service:
- Use 2+ CDN providers for redundancy
- Route traffic based on performance metrics
- Handle CDN failover without user-visible interruption
Use DNS-based routing with real-time health checks. Monitor each CDN's latency per region and shift traffic accordingly. Use a client-side player that can switch CDN mid-stream on error.
# Multi-CDN architecture:
# 1. DNS layer: Route53 / NS1 with latency-based routing
# 2. Health monitor: check each CDN every 30s per region
# 3. Traffic split: 60% primary CDN, 40% secondary
class CDNRouter:
cdns = {
'cloudflare': {'weight': 60, 'healthy': True},
'fastly': {'weight': 40, 'healthy': True},
}
def get_cdn_url(self, asset_path, user_region):
# Filter to healthy CDNs
healthy = {k: v for k, v in self.cdns.items()
if v['healthy']}
# Weighted random selection
cdn = weighted_choice(healthy)
return f"https://{cdn}.example.com{asset_path}"
# Client-side failover (video player)
# If primary CDN returns error, switch to fallback URL
# Player maintains a list of CDN URLs per segment
Quick Reference
Cache-Control Header Cheat Sheet
| Directive | Meaning | Use Case |
|---|---|---|
public |
CDN and browser can cache | Static assets, public pages |
private |
Only browser can cache, not CDN | User-specific content (dashboard, profile) |
no-cache |
Can cache but must revalidate before serving | HTML pages that change frequently |
no-store |
Do not cache at all | Sensitive data (bank statements, tokens) |
max-age=N |
Cache for N seconds | All cacheable content |
immutable |
Content will never change at this URL | Versioned static assets (hash in filename) |
stale-while-revalidate=N |
Serve stale for N seconds while refreshing | API responses, product pages |
Key Takeaways
- CDNs reduce latency by serving content from the nearest edge location
- Pull CDNs are simpler to set up; push CDNs give you more control
- Cache busting (versioned URLs) is the most reliable invalidation strategy
- Edge computing runs logic at the edge for sub-millisecond responses
- Use multi-CDN for critical services that need maximum availability
- Never cache user-specific or sensitive data on shared CDN edge servers