Content Delivery and Edge Computing: CDN, Geo-DNS, and Edge Caching
Design global low-latency systems with CDNs, static and dynamic caching, edge compute, geo-DNS, cache invalidation, and origin protection.
Start With a Video That Buffers Forever
A video learning platform has users in 40 countries. The origin servers are in a single data center in Virginia, US-East. A user in Mumbai opens the app. The browser requests the JavaScript bundle — 300KB. The request travels from Mumbai to a Virginia data center and back: a round trip of roughly 250 milliseconds.
But it is not one request. It is 47: the HTML page, three JavaScript bundles, twelve CSS chunks, twenty-two thumbnail images, six video metadata API calls, a WebSocket for progress tracking, and two analytics pings. Every request makes that 250ms round trip. Total page load time: 4.2 seconds.
A user in Sydney fares worse: 350ms round trip per request. Total: 8.1 seconds.
The platform has plenty of server capacity. The database is fast. The code is optimized. The problem is distance. Light travels at 200km per millisecond in fiber. From Mumbai to Virginia and back, the physics alone costs the network overhead and routing delays.
The solution is not a faster origin. The solution is putting content closer to users.
The fastest request is the one that never reaches your origin. A CDN eliminates the distance penalty by caching content at hundreds of locations worldwide. A user in Mumbai gets JavaScript from Mumbai, not from Virginia.
What a CDN Does
A Content Delivery Network is a globally distributed network of proxy servers deployed in hundreds of locations — points of presence (PoPs) — that cache and serve content from the location nearest to each user.
| Term | Meaning |
|---|---|
| Edge location (PoP) | A CDN server facility near users — thousands exist globally |
| Origin | Your server or storage bucket where the canonical content lives |
| Cache hit | Content served from the edge — fastest path (10–50ms) |
| Cache miss | Edge fetches from origin — incurs full round-trip latency once |
| TTL | Time-to-live — how long the edge keeps content before rechecking |
| Purge | Explicit command to remove cached content across all edge locations |
Why Not Just Serve Everything From the Origin?
Beginners often ask: "Can we just buy a bigger server? Add more regions?"
| Approach | Problem |
|---|---|
| Bigger origin server | Does not reduce network distance. A Mumbai user still waits 250ms per request regardless of how powerful the Virginia server is |
| More origin servers in more regions | Expensive and operationally complex. You need to manage data replication, load balancing, and failover across regions |
| Just use a cloud CDN without planning | CDNs cache blindly. Without proper cache headers and invalidation strategy, users see stale content or miss the cache entirely |
| HTTP/2 multiplexing | Reduces connection overhead but does not reduce round-trip time. The 250ms physical latency per request remains |
A CDN does not just cache. It terminates TCP connections at the edge, optimizes TLS negotiation, compresses responses, coalesces requests, and routes around internet congestion. The origin does one thing: serve content. The CDN does everything else.
A CDN without cache headers is just a slow proxy. If every response has Cache-Control: no-cache or the cache key is not configured correctly, every request passes through the edge to the origin. You pay CDN bandwidth costs without getting CDN latency benefits.
Step 1: Decide What to Cache
Not all content can or should be cached at the edge.
| Content Type | Cache Strategy | TTL | Why |
|---|---|---|---|
Hashed static assets (app.a8f3.js, style.4b2c.css) | Immutable cache | 1 year | Hash changes when content changes. Never needs purge |
| Images and video | Long cache with edge transforms | 30 days | Large payloads benefit most from edge serving. CDN can resize, reformat, and compress at the edge |
| Public HTML pages | Short TTL or stale-while-revalidate | 60 seconds | Fresh enough for most content. Stale-while-revalidate prevents origin hammering |
| Public API responses | Short TTL, cache-keyed by URL + query params | 10–60 seconds | Product listings, search results, leaderboards. TTL depends on staleness tolerance |
| Personalized pages | Private browser cache only | No shared cache | User-specific content should not be served to other users |
| Authenticated API responses | No CDN cache | Never | Auth headers, user IDs, and session data vary per request |
Step 2: Configure Cache Headers
The origin tells the CDN (and the browser) how to cache via HTTP headers.
Immutable Assets (Content-Hashed)
Cache-Control: public, max-age=31536000, immutable
Use for app.a8f3.js, style.4b2c.css — files whose filename includes a content hash. The hash guarantees that a new deploy produces a new URL. The old URL never needs updating. The immutable directive tells the browser it never needs to revalidate on page reload.
Public Content That Changes
Cache-Control: public, max-age=60, stale-while-revalidate=300
Use for news articles, product pages, or any public content that updates occasionally. The CDN serves the cached version for 60 seconds. If a request arrives after 60 seconds but within the 300-second stale window, the CDN returns the stale version immediately and fetches the fresh version in the background. The user never waits.
User-Specific Content
Cache-Control: private, no-store
Use for dashboards, account settings, and any authenticated response. The private directive allows the browser to cache it but prevents shared CDN caches from serving it to other users. Use no-store for highly sensitive data like payment confirmations.
Cache keys must include the right dimensions. If the response differs by language (Accept-Language), device (User-Agent), or authorization level, the cache key must account for these. A user in France requesting /api/products should not receive the cached English response from a previous user in Japan. Configure the CDN to include the relevant headers, cookies, or query parameters in the cache key.
Step 3: Choose Caching Strategies
Strategy A: TTL-Based Caching
Set a max-age and let time decide when to revalidate. Simplest approach. Works well when the cost of serving slightly stale content is low.
Best for: Public API responses, images, HTML pages that change infrequently.
Trade-off: Too short a TTL defeats caching. Too long a TTL risks serving stale content. There is no perfect TTL — only a trade-off between freshness and performance.
Strategy B: Stale-While-Revalidate
Serve stale content instantly, refresh in the background. This eliminates the cache-miss penalty for the user while keeping the cache fresh.
Best for: News sites, product pages, any content where slightly stale is acceptable but fast delivery is critical.
Trade-off: Background refreshes increase origin load slightly during cache-warming periods. The stale window must be short enough that users do not notice.
Strategy C: Content Hashing
The filename includes a cryptographic hash of the content. When the content changes, the URL changes. The old URL is never updated — it simply falls out of use.
app.a8f3d9.js → cache for 1 year
app.7b2e1c.js → cache for 1 year (new version, different URL)
Best for: JavaScript bundles, CSS files, fonts, and any asset generated at build time.
Trade-off: Requires build-time hashing and updating references in HTML. Old versions accumulate in CDN storage.
Strategy D: Versioned Paths
/api/v1/products → cached with TTL
/api/v2/products → cached with TTL (new version, different path)
Best for: API responses, documentation, SDK downloads.
Trade-off: Old versions must be maintained and eventually deprecated.
Step 4: Plan Cache Invalidation
Invalidation is the hardest operational part of CDN caching. A purge command travels to every edge location and removes cached content. But purging is slow (tens of seconds to minutes for global propagation), expensive (many CDNs charge per purge), and easy to get wrong.
| Strategy | How It Works | When to Use |
|---|---|---|
| Content hashing | URL changes when content changes | All static build artifacts. No purge needed |
| Short TTL | Content self-invalidates after max-age | Dynamic public data. Trade-off: more origin requests |
| Purge by URL | Send purge request for a specific path | Emergency content removal (wrong price, security issue) |
| Purge by tag | Tag related content during deploy, purge by tag | Product catalog: purge all /products/* when inventory changes |
| Versioned paths | /v2/ replaces /v1/ — old path naturally expires | API versions, documentation versions |
Prefer versioning over purging. Content hashing for static assets and versioned paths for APIs eliminate the need for most purges. Use purge only for emergencies. A system that depends on purge for every deploy is fragile — if the purge fails silently, users see stale content and nobody notices.
Step 5: Route Users to the Right Region
Geo-DNS returns different DNS records based on where the user's DNS resolver is located. This directs a user in Mumbai to the Mumbai edge region and a user in London to the London region.
| Routing Policy | How It Works | Best For |
|---|---|---|
| Geo routing | Returns different IPs based on the user's country or region | Data residency compliance, region-specific content, language-based routing |
| Latency routing | Probes health and latency from each edge to the origin, routes users to the fastest healthy region | Global applications where performance is the priority |
| Weighted routing | Sends a percentage of traffic to each region | Gradual rollouts, canary deployments, A/B testing |
| Failover routing | Routes all traffic to a secondary region when the primary is unhealthy | Disaster recovery, multi-region active-passive setups |
DNS TTL Trade-offs
DNS responses are cached by ISPs, corporate resolvers, and browsers. A DNS record with a 24-hour TTL means a failover or routing change takes up to 24 hours to propagate.
| TTL | Benefit | Drawback |
|---|---|---|
| 30 seconds | Near-instant routing changes | More DNS queries (cost, latency overhead) |
| 5 minutes | Good balance for most production systems | Failover takes minutes |
| 24 hours | Cheap, low DNS query volume | Routing changes take a full day to propagate |
DNS caching means failover is not instant. If us-east goes down, DNS records pointing to us-east are cached by ISPs for the TTL duration. Users keep hitting a dead region until their DNS cache expires. Always set TTLs low (60–300 seconds) for production DNS records that serve as failover targets.
Step 6: Run Code at the Edge
Edge computing runs lightweight code at CDN PoPs — before the request reaches the origin. This is not a replacement for your application server. It is a filter, a transformer, and a guard that runs close to the user.
Good Edge Workloads
| Workload | Why It Fits | Example |
|---|---|---|
| URL redirects | Simple logic, must be fast | /country/india → /in/ based on geo |
| Header normalization | Must run before cache key lookup | Strip utm_ params, normalize Accept-Language |
| Bot filtering | Stop bad traffic before it reaches origin | Block requests from known bot IPs or missing user-agent |
| A/B routing | Assign variant before origin serves | Route 10% of traffic to v2/api/, 90% to v1/api/ |
| Image transformation | Avoid origin processing for every variant | Resize, reformat (WebP), compress at edge on cache miss |
| JWT verification | Lightweight auth before origin | Verify token signature at edge, reject invalid tokens without hitting origin |
| Rate limiting | Distribute rate limit enforcement globally | Block 429 clients per second at edge before they consume origin resources |
Poor Edge Workloads
| Workload | Problem |
|---|---|
| Heavy database transactions | Data lives in the origin region, not at the edge. Every query requires a long-haul round trip |
| Long-running jobs | Edge runtimes enforce execution limits (10–50 seconds for most providers) |
| Complex business workflows | Edge runtimes are harder to debug, log, and monitor than application servers |
| Sensitive writes | Consistency guarantees, audit trails, and idempotency are harder to enforce at the edge |
Edge vs Serverless: Edge functions run at every CDN PoP (thousands of locations), have lower latency, but stricter limits (memory, execution time, package size). Cloud serverless functions run in a few data centers, have fewer limits, and can access databases and queues directly. Choose edge for request-level transformations. Choose serverless for application logic.
Step 7: Protect the Origin
A CDN should reduce origin load, not just accelerate content delivery. Without origin protection, a traffic spike or cache-miss storm can overwhelm the origin.
| Technique | How It Works | Why |
|---|---|---|
| Request coalescing | When 100 users request the same uncached URL simultaneously, the CDN sends one request to the origin and distributes the response to all 100 | Prevents the thundering herd problem on cache miss |
| Origin shield | An intermediate cache layer between edge PoPs and the origin. Edge misses go to the shield, not directly to the origin | Reduces origin load from thousands of edges to a single shield per region |
| Edge rate limiting | Enforce request limits at the CDN before traffic reaches origin | Blocks abusive clients without consuming origin resources |
| WAF rules | Web Application Firewall at the edge inspects and blocks malicious requests | SQL injection, XSS, and path traversal attacks never reach the application |
| Bot detection | Identify and rate-limit or block automated traffic | Scrapers, credential stuffers, and crawlers consume origin capacity |
| Cache warming | Pre-populate the CDN cache after a deploy by requesting the most popular URLs | Prevents a cold-cache storm where thousands of users hit the origin simultaneously after a deploy |
Common Failure Stories
Story 1: The Purge That Did Not Propagate
A news website published a breaking story with an incorrect stock price. The editor fixed the typo in the CMS and issued a CDN purge for the article URL. The purge completed in 200ms — according to the CDN dashboard. But the CDN's purge propagation to all 200 edge locations took 47 seconds. During those 47 seconds, users in Australia and Brazil still saw the wrong stock price. A trading bot scraped the incorrect price and triggered automated trades.
Root cause: Assuming purge is instant. CDN purge commands are asynchronous. Propagation time depends on the number of edge locations and the purge API's internal queue.
Fix: For time-sensitive content, use short TTLs (60 seconds) with stale-while-revalidate. The correction propagated within 60 seconds automatically. Purge was reserved for emergencies where 60 seconds was too long.
Story 2: The Country That Was Served Japan
A streaming platform used geo-DNS to route users to the nearest region. A major ISP in Australia changed its DNS resolver infrastructure overnight. The new resolvers returned IP geolocation data showing Australian users as located in Japan. Every Australian user was routed to Tokyo. Latency went from 50ms to 250ms. Streaming quality dropped from 4K to 480p. Support tickets flooded in for three days before the ISP fixed its resolver data.
Root cause: Geo-DNS relies on the DNS resolver's IP location, not the user's actual location. ISP resolvers can be in different regions, behind VPNs, or misconfigured.
Fix: Added latency-based routing as a fallback. If geo-routing sends a user to a region with latency above 150ms, the DNS system probes alternative regions and routes to the fastest one. The issue was detected automatically within five minutes instead of three days.
Geo-DNS is a hint, not a guarantee. A user's DNS resolver may be in a different country than the user. Always pair geo-routing with latency probes or EDNS Client Subnet (ECS) for more accurate user location.
Story 3: The Cache Key That Merged Two Users
A SaaS application cached API responses at the CDN edge. The cache key included the URL and query parameters but not the Authorization header. User A (admin) requested /api/users and received the full user list — which was cached at the edge. User B (viewer) requested the same URL and received User A's cached response: a full user list that User B should not have seen.
Root cause: Cache key did not include authorization context. The CDN treated both requests as identical and served the first response to the second user.
Fix: Added the authorization level to the cache key. For authenticated endpoints, either include the user's role/permission level in the cache key or set Cache-Control: private to prevent shared caching entirely.
Story 4: The Cold Cache Stampede
An e-commerce site deployed a new version of their homepage with updated CSS hashes. The deploy tool purged all CDN cache for the new paths. The CDN cache was now empty for every asset. The first 50,000 users after the deploy hit the origin simultaneously for JavaScript, CSS, images, and API responses. The origin servers, which normally handled 500 req/s, received 8,000 req/s. The database connection pool saturated. The site was down for 14 minutes.
Root cause: Deploy + full cache purge + no cache warming = simultaneous origin stampede.
Fix: Added cache warming to the deploy pipeline. After the purge, a script requested the top 100 most-visited URLs from each global region. The cache was populated before the first real user arrived. The stampede never happened again.
Story 5: The Image That Would Not Update
A product manager updated a product image on an e-commerce site. The product page URL did not change. The image URL did not change. The CDN had cached the old image with a 30-day TTL. After 28 days, users still saw the old image. The PM filed a urgent bug. The engineering team purged the image URL. The fix took effect within 30 seconds. But the PM had already told the CEO "the CDN is broken."
Root cause: The image URL was content-hashed but the product page was not — the page referenced product.jpg instead of product.a8f3.jpg. Without a URL change, the CDN served the old version for the entire TTL.
Fix: All user-uploaded images were given content-hashed filenames at upload time. A new image got a new URL. The old URL was never purged — it naturally expired from the CDN when users stopped requesting it.
Evaluation: How to Test CDN Performance
Key Metrics
| Metric | What It Measures | Target |
|---|---|---|
| Cache hit ratio | Percentage of requests served from edge without hitting origin | > 90% for static assets, > 70% for API responses |
| Time to first byte (TTFB) | Time from request to first byte received by user | < 100ms for cache hits, < 300ms for cache misses |
| Origin offload | Percentage of total traffic absorbed by the CDN | > 85% |
| Purge propagation time | Time for a purge to reach all edge locations | < 10 seconds for urgent, < 60 seconds for normal |
| Error rate at edge | Percentage of edge responses that are 5xx | < 0.1% |
Testing Scenarios
| Test | What It Validates | How |
|---|---|---|
| Cache hit verification | Correct cache headers produce cache hits | Request URL with recommended Cache-Control, verify x-cache: hit header in response |
| Multi-region latency | Users everywhere get low latency | Measure TTFB from 10+ global locations (use synthetic monitoring or RUM) |
| Cache key correctness | Different authorized users get different responses | Request same URL with different Authorization headers, verify responses differ |
| Purge propagation | Purge takes effect within acceptable time | Cache an object, issue a purge, verify it is removed from multiple edge locations over time |
| Cold cache behavior | Origin handles cache-miss storms without failing | Flush the CDN cache, send traffic at expected peak rate, measure origin load |
| Geo-DNS routing | Users route to correct region | Query DNS from different global locations, verify correct IP ranges returned |
End-to-End Global Delivery Architecture
Interview Prep
Content delivery and edge computing is a common topic in system design interviews for global-scale applications.
Common Interview Questions
-
Design YouTube's content delivery infrastructure. Start with the three content types: static assets (hashed URLs, 1-year TTL, immutable), video segments (long TTL, edge transforms for quality/resolution, range requests), and API responses (short TTL with user-specific cache keys). Add geo-DNS for regional routing, origin shield to protect the video transcoding pipeline, and cache warming for popular uploads.
-
How would you invalidate cached content across 200 edge locations in under 5 seconds? You cannot. Purge commands are asynchronous and propagate as fast as the CDN's internal network allows. Instead, design around invalidation: use content hashing for static assets (new URL = automatic invalidation), short TTLs for dynamic content (60 seconds of staleness is usually acceptable), and versioned paths for APIs. Use purge only for emergencies.
-
A user in India is getting 800ms latency even with a CDN. What do you check? First, verify the CDN has a PoP in India and the geo-DNS is routing correctly (check DNS resolution from India). Second, check cache hit ratio — if the user's requests are all unique (personalized API responses), they are cache misses passing through to a far-away origin. Third, check if the origin is in a different region (US-East) and whether an origin shield in Asia would help.
-
How do you handle authenticated content at the edge? Use edge functions to verify JWT tokens before the request reaches the origin. If the token is invalid, reject at the edge. If valid, forward the request with the user's authorization level as a header. Configure the cache key to include the authorization level so admins and viewers receive different cached responses. Never cache sensitive user data in shared caches.
-
Compare CDN caching versus application-level caching. CDN caching is coarse-grained (URL-level), globally distributed, and requires no application changes — just correct Cache-Control headers. Application-level caching (Redis, Memcached) is fine-grained (partial responses, computed values), colocated with the application, and supports complex invalidation logic. Use both: CDN for public, cacheable content; application cache for personalized or computed data.
-
Your origin is in US-East but you have users in Australia and Europe. How do you design the global architecture? CDN edges in Sydney, Singapore, Frankfurt, and London serve cached content. Geo-DNS routes each user to the nearest edge. An origin shield in each continent reduces long-haul traffic. For dynamic API requests that cannot be cached (user-specific), deploy the application server in three regions (US, EU, APAC) with global database replication. The CDN handles static and quasi-static content; multi-region servers handle dynamic content.
Key Takeaways
- CDNs exist because physics limits speed. Light in fiber takes 200ms per 1,000km round-trip. No amount of server optimization changes that. Edge caching is the only solution for global latency.
- Cache headers are the contract between origin and CDN.
max-age,stale-while-revalidate,immutable, andprivatedetermine whether the CDN helps or acts as a slow proxy. - Cache invalidation is the hard part. Prefer content hashing and short TTLs over purging. A purge-dependent invalidation strategy is fragile.
- Cache keys must be correct. Include language, device, and authorization level in the cache key — or use
privateto prevent shared caching for user-specific content. - Geo-DNS is a hint, not a guarantee. Pair with latency-based routing and EDNS Client Subnet for accuracy. Use low DNS TTLs for failover scenarios.
- Edge compute is for lightweight work. URL rewrites, auth verification, bot filtering, and A/B assignment. Heavy workflows belong in the origin application server.
- CDNs protect the origin. Request coalescing, origin shield, rate limiting, and WAF rules prevent the origin from seeing thundering herds and malicious traffic.
Practice exercise: Design global content delivery for a video learning platform with users in 40 countries. Define cache strategies for three content types (static assets, video segments, API responses), choose a geo-DNS routing policy, decide which workloads to run at the edge (JWT verification, thumbnail resizing, A/B assignment), plan a purge-free invalidation strategy using content hashes and versioned paths, and design an origin protection layer with request coalescing and an origin shield per continent.