Home  /  CDN Architecture  /  CDN Eventual Consistency
CDN Architecture Alex Petrov, DevOps & Infrastructure Engineer September 8, 2026 9 min read

CDN Eventual Consistency: Managing Cache Coherence Across Global PoPs

A CDN is a distributed cache, not a distributed database. Understanding its eventual consistency model is the key to delivering fast, coherent content without sacrificing availability at the edge.

When you deploy content to a CDN with 300+ Points of Presence, you are not pushing to a single coherent store. You are replicating state across an eventually consistent system where each PoP operates as an autonomous cache. An update at your origin in Virginia does not instantly appear in Singapore, São Paulo, or Frankfurt. For a window of time — seconds to minutes depending on your strategy — different users will see different versions of the same URL.

This is not a bug. It is the fundamental trade-off that makes CDNs fast. Strong consistency would require synchronous coordination between PoPs on every read, destroying the latency benefits you adopted a CDN for in the first place. The engineering challenge is not to eliminate eventual consistency, but to manage it deliberately. If you are new to how edge caching works, start with our what is a CDN primer, then dive into the patterns below.

Why Strong Consistency Fails at the Edge

In a traditional database, strong consistency means that after a write completes, all subsequent reads return the updated value. Achieving this across a global CDN would require a consensus protocol like Paxos or Raft between PoPs before acknowledging a write. With round-trip times of 100-250ms between continents and hundreds of nodes, that coordination would add seconds of latency to every purge and origin fetch.

CDNs therefore choose availability and partition tolerance over strong consistency, as described by the CAP theorem. Each PoP serves from its local cache independently, even if it is disconnected from the origin or from other PoPs. The system guarantees that, in the absence of new writes, all PoPs will eventually converge to the same state — hence eventual consistency.

Three factors determine your consistency window:

Core Principle

Treat every cached object as having a coherence SLA. Define how stale it is allowed to be, then select a pattern that enforces that SLA with minimal operational cost. Not all content needs the same consistency.

Consistency Models You Can Choose

Not all eventual consistency is equal. You can tune the model per content type using HTTP cache directives and CDN configuration. Understanding these models helps you match business requirements to technical implementation, as detailed in our CDN fundamentals guide.

Performance Comparison: Edge vs Origin Processing
Metric Edge Processing Origin Processing Improvement
Latency (p50)8–15 ms120–300 ms15–20x faster
Cache Hit Ratio85–95%N/AReduces origin load
TLS Handshake1–5 ms (nearby PoP)50–150 ms10–30x faster
Bandwidth Cost$0.01–0.04/GB$0.05–0.12/GB3–5x cheaper
Availability99.99% (multi-PoP)99.9% (single DC)10x fewer outages

1. TTL-Based Expiration (Passive Coherence)

The simplest model. You set Cache-Control: max-age=60, s-maxage=300 and each PoP expires the object independently. No control plane messages are needed. Consistency is bounded by the TTL value. This is ideal for content where a few minutes of staleness is harmless, such as blog posts or product descriptions.

2. Active Invalidation (Purge)

You explicitly tell the CDN to drop an object via API. The CDN broadcasts the invalidation to all PoPs. This provides much tighter coherence but introduces control plane dependency and cost. Most providers charge or rate-limit purges, and excessive purging negates caching benefits.

3. Versioned / Fingerprinted URLs (Immutable Coherence)

Instead of mutating /app.css, you deploy /app.a3f9c1.css. The URL itself becomes the version. Old and new versions coexist without conflict, and coherence is perfect because there is no mutation. This is the gold standard for static assets and should be your default for build artifacts.

4. Stale-While-Revalidate (SWR)

Defined in RFC 5861, SWR allows a PoP to serve stale content while revalidating in the background: Cache-Control: max-age=60, stale-while-revalidate=30. Users never wait for origin, but may see content up to 90 seconds old. It smooths latency spikes during revalidation.

CDN Eventual Consistency Propagation Across PoPs Diagram showing origin update propagating to global PoPs over time with consistency window. ORIGIN us-east-1 v2 deployed t=0s t=0.8s t=1.5s t=60s PoP Frankfurt v2 ✓ (180ms) PoP Singapore v2 ✓ (620ms) PoP São Paulo v1 stale (1.4s) SHIELD parent cache coalescing CONVERGED ✓ All PoPs serving v2 TTL window closed INCONSISTENCY WINDOW — eventual consistency
Figure 1: Purge propagation is not instantaneous. Shield and leaf PoPs converge at different times, creating a bounded inconsistency window.

Five Patterns for Managing Coherence

The right pattern depends on content mutability, traffic volume, and tolerance for staleness. Most production architectures combine several.

Pattern Consistency Best For Trade-off
Short TTL
max-age 30-60s
Bounded ~60s News, pricing, inventory Lower hit ratio, higher origin load
Surrogate Keys
Tag-based purge
Strong ~1s CMS pages, product catalogs Requires origin tagging logic
Versioned URLs
/asset.[hash].js
Perfect JS, CSS, images, fonts Build pipeline complexity
Stale-While-Revalidate
SWR 30-300s
Weak ~90s APIs, SSR pages Clients may see stale data
Global Purge All
/* invalidation
Eventual 2-15s Emergency rollback only Thundering herd, cache cold start

For high-cardinality content like e-commerce catalogs, surrogate keys are the most scalable active pattern. Instead of purging by URL, you tag responses with keys like product-123 or category-shoes and purge by tag. A single API call invalidates thousands of URLs across all PoPs without enumerating them. This is far more efficient than URL-based purging and integrates cleanly with your CDN SSL/TLS configuration and edge logic.

Invalidation vs. Expiration: Implementation

Expiration is declarative and origin-driven; invalidation is imperative and control-plane-driven. Prefer expiration wherever possible. It is cheaper, more reliable, and does not depend on the CDN's purge queue.

Expiration Headers (Preferred)

Set tiered TTLs to balance hit ratio and freshness. Use s-maxage for shared caches and max-age for browsers.

# Origin response headers for a product API
Cache-Control: public, s-maxage=60, max-age=30, stale-while-revalidate=30, stale-if-error=86400
Surrogate-Key: product-4821 category-footwear brand-nike
CDN-Cache-Control: max-age=60
Vary: Accept-Encoding, Accept-Language

This tells PoPs to cache for 60 seconds, serve stale for 30 seconds while revalidating, and keep stale for 24 hours if origin is unreachable. Browsers cache for 30 seconds. The surrogate keys enable targeted purging later.

Targeted Invalidation (When You Must)

When price or inventory changes, purge by surrogate key rather than waiting for TTL expiry:

# Purge by surrogate key via CDN API (Fastly / Cloudflare / Akamai pattern)
curl -X POST \
  -H "Fastly-Key: $FASTLY_API_TOKEN" \
  -H "Accept: application/json" \
  https://api.fastly.com/service/SERVICE_ID/purge/product-4821

# Cloudflare equivalent with cache-tags
curl -X POST \
  -H "Authorization: Bearer $CF_TOKEN" \
  -d '{"tags": ["product-4821"]}' \
  https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache

For atomic deployments, combine versioned URLs with a short-TTL HTML shell. The HTML at /index.html has s-maxage=30 and references /main.a3f9c1.js immutably cached for a year. Purging only the HTML is enough to roll forward, and rollback is instant by re-purging the previous HTML.

Avoid Purge-All

A wildcard purge (/*) evicts the entire cache and forces every PoP to refetch from origin simultaneously. On high-traffic sites this causes origin overload and latency spikes. Reserve it for security incidents. For load distribution during revalidation, use CDN load balancing algorithms with origin shielding.

Monitoring Coherence and Measuring Drift

You cannot manage what you do not measure. Instrument your edge to detect drift before users do.

Set SLOs per content class: 5 seconds for pricing, 60 seconds for CMS, infinite for fingerprinted assets. Use tiered caching and CDN DDoS protection shielding to absorb revalidation storms — a shield PoP coalesces concurrent misses into a single origin request, protecting your origin during convergence.

Choosing Your Strategy

Start with this decision tree: Is the asset immutable? Use versioned URLs with immutable and a one-year TTL. Is it mutable but taggable? Use short TTL (30-60s) plus surrogate-key purge. Is it highly dynamic and personalized? Bypass cache or use private, no-store and cache at the application layer instead.

Eventual consistency is not a compromise to work around — it is the mechanism that lets your site serve 95%+ of requests from the edge at <50ms. By making coherence explicit through TTLs, surrogate keys, and versioning, you turn an unpredictable distributed system into a predictable one with bounded staleness and clear operational playbooks.

Frequently Asked Questions

How long does CDN eventual consistency typically take?

With active purge, most tier-1 CDNs achieve global coherence in 150ms to 2 seconds. With TTL-only expiration, consistency depends on your max-age: a 60s TTL means up to 60s drift, while a 1-hour TTL means up to 1-hour drift across PoPs.

Should I use purge or versioned URLs for cache coherence?

Use versioned URLs (fingerprinting) for static assets like JS, CSS, and images where immutability is possible. Use purge or surrogate-key invalidation for dynamic content like HTML, API responses, and personalized pages where versioning is impractical.

Does stale-while-revalidate break consistency?

Stale-while-revalidate intentionally trades strict coherence for availability and latency. Clients may receive stale content for the SWR window (e.g., 30–60s) while the edge revalidates asynchronously. It's ideal for content where brief staleness is acceptable.

How do I prevent thundering herd after a global purge?

Combine soft purge with stale-while-revalidate, use request coalescing via origin shield, and implement tiered caching. This allows one PoP to revalidate while others serve stale, preventing thousands of edge nodes from hitting origin simultaneously.

References & Standards: RFC 7234 · W3C Web Performance