CDN — Content Delivery Network
A network of geographically distributed servers that delivers content to users from the closest node, reducing latency and offloading the origin server — at the cost of dealing with cache invalidation and eventual consistency at the edge.
Intent
A CDN distributes copies of content across servers spread around the world so each user is served by the geographically closest node. Instead of every request crossing oceans to reach the origin server, it's answered by a local PoP (Point of Presence) — reducing round-trip time (RTT) from hundreds of milliseconds to tens.
The benefit is twofold: lower latency for the user (data travels less physical distance) and reduced load on the origin server (most requests are absorbed by the PoPs without ever reaching the origin). CDNs are the outermost cache layer of a web system and are practically mandatory in any product with a geographically distributed audience.
Problem
The speed of light imposes a physical limit on network latency: a packet between São Paulo and Frankfurt takes approximately 100–120 ms of RTT alone, even under ideal conditions. In systems where the origin server lives in a single region, distant users pay that cost on every request.
- Geographic latency: a European user accessing a server in the US pays 80–150 ms of RTT for every resource loaded. A page with 30 assets can easily accumulate seconds of network latency before any processing even happens.
- Origin overload during spikes: a product launch or a viral event can multiply traffic a hundredfold in minutes. Without absorption at the edge, all that volume hits the origin server directly, which frequently doesn't have capacity for the spike.
- Origin bandwidth cost: transferring gigabytes or terabytes of video, images, and assets from a single datacenter is expensive — both financially and in bandwidth. Distributing that traffic across the PoPs reduces the origin's egress cost.
- Availability and resilience: a single origin server is a point of failure. If it's unavailable, no user can access the content — unless there's an edge layer serving cached content during the outage.
How it works
PoP (Point of Presence)
Each node of a CDN is called a PoP: a server (or cluster of servers) with local storage installed in a datacenter close to a concentration of users. The CDN redirects each user to the geographically closest PoP via DNS or Anycast IP.
User (BR, São Paulo)
│
▼
┌─────────────────┐
│ CDN PoP SP │ cache HIT?
│ (São Paulo) │──────────────► Response (low latency)
└────────┬────────┘
│ cache MISS
▼
┌─────────────────┐
│ Origin Server │
│ (USA) │──► populates cache on the PoP ──► Response
└─────────────────┘
User (EU, Frankfurt)
│
▼
┌─────────────────┐
│ CDN PoP FRA │ cache HIT?
│ (Frankfurt) │──────────────► Response (low latency)
└─────────────────┘
Cache HIT vs MISS
When a user requests a resource:
- HIT: the PoP has a valid cached copy and returns it directly, without contacting the origin. Minimal latency — just the distance to the PoP.
- MISS: the PoP doesn't have the resource (or the cache expired). The PoP fetches it from the origin, stores the response locally, and returns it to the user. The next request for the same resource will be a HIT.
The HIT rate is a CDN's central metric: the higher it is, the more efficient the distribution and the less traffic reaches the origin. Rates below 80–90% for static content usually indicate problems in TTL configuration or caching strategy.
Cache-Control and TTL
The origin server defines how long a PoP can store and serve a
resource via the HTTP Cache-Control header. The
max-age value specifies the TTL in seconds:
# Static asset with hash — long TTL (1 year)
Cache-Control: public, max-age=31536000, immutable
# HTML — short TTL (no cache or short, since it changes frequently)
Cache-Control: no-cache
# Public API response — medium TTL (5 minutes)
Cache-Control: public, max-age=300, s-maxage=300
# Response with private data — must not be cached on the CDN
Cache-Control: private, no-store
A long TTL means fewer calls to the origin and a higher hit rate, but more risk of serving stale content. A short TTL guarantees fresh data, but reduces cache efficiency.
Cache invalidation
Forcing a PoP to discard cached content before the TTL expires is called invalidation. It's needed when a new deploy must be served immediately without waiting for the TTL.
The problem: invalidation needs to propagate to every PoP in the network, which takes time (seconds to minutes) and has a cost — many CDNs charge per invalidation operation, and propagation isn't instantaneous.
The most robust strategy is URL-based cache busting: including a content hash in the filename. When the file changes, the URL changes, the cache is naturally bypassed (since it's a new URL), and the old file expires via its TTL normally.
# Without cache busting — problem when deploying
/static/app.js # same URL, PoP serves the old version
# With cache busting — safe deploy
/static/app.a3f9b2c1.js # new URL on every build, PoP always fetches
/static/app.min.js?v=42 # alternative: query string with a version
Content types: static vs dynamic
- Static content (ideal for CDN): images, CSS, JavaScript, fonts, videos — don't vary by user and change rarely. HIT rates close to 100% are achievable. This is the case the CDN was originally built for.
- Dynamic content (CDN can help partially): API responses personalized per user have a composite cache key (URL + authentication headers), resulting in a low hit rate by definition. Even so, the CDN's geographic routing reduces network latency even on MISSes — the PoP acts as a reverse proxy close to the user, forwarding to the origin faster than the user could reach it directly.
Pull CDN vs Push CDN
PULL CDN (more common) PUSH CDN
User request You proactively push content
│ to the PoPs before any
▼ request happens.
PoP checks cache
│ MISS Good for: large and predictable
▼ content (videos, downloadable
PoP fetches from origin files), where a MISS on a
and populates the cache Pull CDN would be costly.
Simple to operate. Higher complexity: you manage
PoPs are populated on which files live on which
demand (lazy). PoPs.
First user per PoP
pays the MISS cost.
When to use
- Static assets with a global audience: images, JavaScript, CSS, and fonts for any product with users in more than one region. The gain is immediate and the setup effort is low.
- Video streaming and large files: serving videos from the origin to thousands of simultaneous users is impractical. The CDN distributes bandwidth load across the PoPs and serves content with less buffering for the end user.
- Protecting the origin against traffic spikes: events with unpredictable traffic (launches, viral campaigns) can be absorbed by the PoPs without requiring the origin to have capacity for the peak load.
- DDoS mitigation: CDNs like Cloudflare and Akamai can absorb volumetric distributed attacks at the edge, before malicious traffic reaches the origin infrastructure.
When to avoid or be careful
- Highly personalized content with a low hit rate: if every user receives a unique, non-shareable response, the CDN acts only as a geographic reverse proxy — useful for reducing network latency, but without the benefit of caching. The cost may not be worth it.
-
Sensitive data without a compliance review:
storing personal or confidential data on third-party servers
(the CDN's PoPs) can violate GDPR, LGPD, or internal
requirements. Responses with
AuthorizationorSet-Cookiemust useCache-Control: privateto never be cached on the PoPs.
Pros and cons
Pros
- Latency reduction proportional to geographic distance: the farther the user from the origin, the greater the gain from the CDN.
- Origin offload: the origin server processes only the MISSes, freeing up capacity for operations that can't be cached.
- Automatic horizontal scalability: the CDN absorbs traffic spikes without requiring additional provisioning at the origin.
- High availability: if the origin becomes temporarily unavailable, the PoP can keep serving cached content (stale-while-revalidate).
- Built-in security: modern CDNs offer DDoS protection, WAF (Web Application Firewall), and TLS termination at the edge.
Cons
- Eventual consistency: after a deploy, users on different PoPs may see different versions of the content until the TTL expires or the invalidation propagates.
- Invalidation cost: propagating invalidations to every PoP has a cost (financial and time) and isn't instantaneous.
- Third-party dependency: the CDN is a critical infrastructure point. A failure at the CDN provider (as happened with Fastly in 2021) can take down services worldwide simultaneously.
- Debugging complexity: cache issues are hard to reproduce locally and diagnose in production — behavior varies by PoP, by TTL, and by headers.
- Transfer cost: CDNs charge for volume of data transferred, which can be significant for video content or apps with many large assets.
Common pitfalls
1. Long TTL without cache busting
Setting Cache-Control: max-age=31536000 on CSS and
JavaScript files without including a hash in the URL is a
dangerous combination. After a deploy, the PoPs keep serving the
old version until the TTL expires — which can be a year. Users
who already visited the site have the file cached in the browser
for that same period.
Rule of thumb: long TTL and URL-hash cache busting go together. A long TTL without a hash in the URL is a deploy bug waiting to happen. Never configure one without the other for assets that change between deploys.
2. Treating expensive, slow invalidation as the default solution
Many teams assume "if we need to, we'll just invalidate." In practice, manual invalidation has a cost, takes minutes to propagate, and doesn't guarantee immediate consistency across all PoPs. Planning the URL versioning strategy before you need to invalidate is more robust — invalidation should be the contingency plan, not the normal flow.
3. Caching responses with user data
Responses that contain Set-Cookie,
Authorization, or user-personalized data must not be
cached on the PoPs. If the Cache-Control: private
header is omitted and the CDN is configured to cache by default,
one user's data can be served to another — a critical data leak.
# WRONG: response with user data not marked as private
HTTP/1.1 200 OK
# no Cache-Control → CDN may cache and serve it to others
# CORRECT: private data must never go into the CDN cache
HTTP/1.1 200 OK
Cache-Control: private, no-store
4. CORS not configured at the origin
Assets (fonts, scripts, images) served by the CDN on a domain different from the main site need CORS headers configured on the origin server. If the PoP caches a response without the correct CORS headers, every user who receives that cached response will have loading failures in the browser — and the problem only resolves once the TTL expires or the invalidation propagates.
Related architectures and patterns
A CDN is a specialized instance of caching — it applies the same principles of TTL, HIT/MISS, and invalidation, but at the geographic edge layer instead of at the application server. The same cache-busting and TTL strategies discussed in Caching apply directly to configuring a CDN.
Load Balancing and CDN are complementary: the load balancer distributes traffic among origin server instances within the same datacenter; the CDN distributes traffic across geographic regions before it even reaches the origin. In modern architectures, traffic passes through the CDN first and only then reaches the origin's load balancer.
The API Gateway frequently operates alongside a CDN: the CDN serves static assets at the edge while the API Gateway manages authentication, routing, and rate limiting for the dynamic calls that need to reach the origin.