CDN Operations

CDN Purge Strategies: Instant, Tag-Based, and Surrogate Key Purging

By Alex Petrov, DevOps & Infrastructure Engineer • September 12, 2026 • 9 min read

Effective cache invalidation is the hardest part of operating a CDN at scale. A stale product price, an outdated API response, or a leaked asset can cost revenue and trust. This guide compares the three core purge strategies — instant purge, tag-based purge, and surrogate key purging — and shows how to implement them for atomic, low-latency invalidation without collapsing your hit ratio.

TL;DR: Use instant (URL) purge for single objects, tag-based purge for logical groups up to hundreds of tags, and surrogate keys for high-cardinality, multi-dimensional invalidation at scale. Never use purge-all in production.

If you are new to edge caching, start with our primers on what is a CDN and how a CDN works before tuning invalidation. Purging is not just a button — it is a distributed systems problem that touches consistency, propagation, and origin protection.

Why Cache Invalidation Is Hard at the Edge

A CDN is a globally distributed, eventually consistent key-value store. When you cache an object at 300+ Points of Presence (PoPs), you create 300+ copies that must be coordinated on update. Time-to-live (TTL) alone is insufficient for dynamic content: a 1-hour TTL means up to an hour of staleness, while a 10-second TTL destroys your performance and origin offload benefits.

Purge fills that gap. It provides an out-of-band control plane to explicitly evict or mark stale objects before their TTL expires. The challenge is propagation speed, granularity, and safety. A naive purge-all is simple but catastrophic — it drops global hit ratio from 95% to 0% and can DDoS your own origin as every edge revalidates simultaneously.

Modern purge systems solve this with three properties:

  • Speed: Global propagation in <300ms via a dedicated purge bus, not DNS or TTL polling.
  • Granularity: Ability to invalidate one URL, a logical group, or a complex intersection of attributes.
  • Atomicity: Purge should be all-or-nothing across PoPs to avoid serving mixed old/new content during deploys.

Understanding these trade-offs is essential for robust cache invalidation and for sites where freshness matters, such as CDN for e-commerce catalogs and pricing.

Strategy 1: Instant Purge (Purge by URL)

Instant purge — also called purge-by-URL or single-object purge — is the most fundamental operation. You send an API request with an exact URL or cache key, and the CDN evicts that object from every edge node.

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

It is precise and predictable. When you update /assets/app.v2.js or /api/products/123, you purge exactly that path. Most providers expose this via REST API, CLI, or control panel, and it typically supports wildcards or prefix purges in limited form.

Example: Instant purge via API (Cloudflare & Fastly) # Cloudflare - purge single URL
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache" \
  -H "Authorization: Bearer CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"files":["https://example.com/products/123","https://example.com/assets/app.v2.js"]}'

# Fastly - instant purge by URL (requires purge key)
curl -X PURGE "https://example.com/api/products/123" \
  -H "Fastly-Soft-Purge: 1"

When to Use Instant Purge

Use it for low-volume, deterministic updates: deployments, CMS publishes, or manual hotfixes. It is ideal when you know the exact URLs that changed. It is also the safest fallback when tag infrastructure is not yet implemented.

Limitations

The bottleneck is cardinality. If a product update affects 50 URLs (product page, category listings, search results, API variants, image derivatives), you must enumerate and purge all 50. Miss one, and you serve stale content. At scale — say 10,000 SKUs updated via feed — you quickly hit API rate limits and operational complexity. Instant purge also cannot express relationships like “purge all pages that contain product 123” without application-level tracking.

Soft purge vs hard purge matters here. A hard purge deletes the object; the next request is a cache miss to origin. A soft purge (e.g., Fastly-Soft-Purge: 1 or stale-while-revalidate) marks the object as stale but allows the edge to serve stale content while revalidating asynchronously, preventing origin spikes. Prefer soft purge for high-traffic objects.

Strategy 2: Tag-Based Purging (Cache-Tag)

Tag-based purging adds an abstraction layer. Instead of purging by URL, you assign one or more logical tags to each cached response via an HTTP header, then purge by tag. All objects bearing that tag are invalidated in one API call.

Cloudflare calls this Cache-Tag, Akamai uses Edge-Cache-Tag, and others use Cache-Tag or Surrogate-Key interchangeably for this tier. The core idea is identical: decouple the cache key (URL) from the invalidation key (business entity).

Example: Tag-based purging — origin response + purge call # Origin response headers (Nginx / App)
HTTP/1.1 200 OK
Cache-Control: public, max-age=86400
Cache-Tag: product-123, category-shoes, brand-nike, collection-summer26

# Later: product 123 price changed - purge all representations
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache" \
  -H "Authorization: Bearer CF_API_TOKEN" \
  --data '{"tags":["product-123"]}'

# Akamai equivalent
curl -X POST "https://akaa-xxx.luna.akamaiapis.net/ccu/v3/invalidate/tag" \
  -H "Content-Type: application/json" \
  --data '{"objects":["product-123"]}'

This is a major operational leap. Updating product 123 now requires one purge call, not 50 URL enumerations. Category pages, search indexes, and API responses that included that product all share the tag and are invalidated atomically.

Designing a Tag Schema

Good tag design mirrors your domain model. For e-commerce, use hierarchical and entity tags: product-{id}, category-{slug}, brand-{id}, user-{id} for personalized fragments. Keep tags lowercase, hyphenated, and bounded. Most CDNs limit tags per response (e.g., Cloudflare: 128 tags, 16KB header) and tags per purge (30-100). Exceeding limits silently truncates, leading to missed invalidations — a common production bug.

Tag-based purging also enables safe deploys. Tag all assets for release v2.1.0 with release-v2.1.0; on rollback, purge that tag instead of hunting URLs.

Limitations

Tag purging is powerful but still constrained by header size and purge API limits. It also requires origin discipline: every cacheable response must emit correct tags. If your image optimizer or edge worker strips headers, tags are lost. You need automated tests that assert Cache-Tag presence on critical routes.

Strategy 3: Surrogate Key Purging — The Scalable Evolution

Surrogate key purging, pioneered by Fastly and now adopted broadly, is the high-cardinality successor to tag-based purging. Technically similar — you assign keys via Surrogate-Key header — but architecturally different: it is designed for thousands of keys per object, atomic multi-key purges, and near-instant global consistency.

The key distinction is in the control plane. Fastly’s surrogate key system stores a reverse index (key → URLs) in a globally replicated database, allowing a single purge request to invalidate millions of objects sharing a key in ~150ms. You can also purge by key combination or use soft-purge and surrogate-key-based revalidation.

Example: Surrogate keys for complex invalidation (Fastly VCL / Origin) # Origin response - product page belongs to many dimensions
Surrogate-Key: product-123 product-type-shoes collection-summer26 color-red size-10 warehouse-us-east
Surrogate-Control: max-age=86400
Cache-Control: public, max-age=60

# Purge all red shoes from summer collection (two keys, atomic)
curl -X POST "https://api.fastly.com/service/SERVICE_ID/purge/product-123" \
  -H "Fastly-Key: FASTLY_API_TOKEN" \
  -H "Accept: application/json"

# Purge multiple keys in one call (API supports up to 256 keys)
curl -X POST "https://api.fastly.com/service/SERVICE_ID/purge" \
  -H "Fastly-Key: FASTLY_API_TOKEN" \
  --data '{"surrogate_keys":["collection-summer26","warehouse-us-east"]}'

Surrogate keys shine for high-cardinality use cases: marketplaces with 500k SKUs, APIs with pagination and filtering, or sites with A/B variants. An API response for /api/search?q=shoes&page=2 might carry 40 surrogate keys (one per product ID on the page). When product 789 updates, purging product-789 instantly invalidates every search page, category page, and recommendation widget that contained it — without the application knowing where it was rendered.

Surrogate Key Purge Flow Diagram showing origin assigning surrogate keys to CDN edge caches and purge by key invalidating multiple objects globally. Origin / App Surrogate-Key: product-123 CACHE CDN Edge (PoPs) /p/shoes-123 [key: product-123] /category/shoes [key: product-123] /api/search?q=shoes [key: product-123] PURGE Purge API purge product-123 ~150ms global All variants invalidated atomic • soft-purge ready
Figure 1: Surrogate key purge — one logical key invalidates all objects sharing it across every PoP in a single atomic operation.

Surrogate keys also enable key composition. You can purge by intersection: “purge all objects with both category-shoes AND brand-nike” by issuing two purges or using provider-specific batch APIs, without over-purging unrelated shoe categories. This is impossible with URL-based purges and cumbersome with limited tag sets.

Operationally, enforce key hygiene: normalize keys (lowercase, no spaces), limit key length (Fastly: 1024 chars per header, 256 keys per purge), and log every purge with actor, reason, and key. Treat surrogate keys as part of your API contract, versioned and documented like any other interface.

Comparison: Which Purge Strategy Should You Use?

Strategy Granularity Propagation Best For Risk
Instant (URL) Purge Single object / exact URL 150–300ms global Deploys, single-page updates, hotfixes Low Missed URLs cause staleness
Tag-Based (Cache-Tag) Logical group (entity, category) 150–300ms global CMS, catalog updates, group invalidation (10s–100s objects) Medium Header limits, tag hygiene
Surrogate Key High-cardinality, multi-dimensional (1000s keys/object) ~150ms atomic global Marketplaces, APIs, personalization, search pages Medium Requires origin discipline
Purge-All Entire cache Seconds, thundering herd Emergency only (key rotation, breach) High Origin overload, 0% hit ratio

Implementation Patterns for Atomic, Safe Purging

Choosing a strategy is only half the work. How you trigger purges determines reliability.

1. Event-Driven Purging, Not Cron

Hook purges to domain events, not timers. When your CMS publishes, your PIM updates a price, or your deploy pipeline finishes, emit an event that purges the affected keys. Use a queue (SQS, RabbitMQ) between your app and the CDN API to handle retries, rate limiting, and audit logging. Never purge synchronously in the request path — a slow CDN API should not block your checkout.

2. Soft Purge + Stale-While-Revalidate

For high-traffic keys, combine soft purge with stale-while-revalidate to avoid dog-piling origin. The edge serves stale content for a few seconds while fetching fresh data in the background. This pattern is critical during flash sales or breaking news.

Soft purge with stale-while-revalidate headers Surrogate-Key: product-123 category-shoes
Surrogate-Control: max-age=86400, stale-while-revalidate=60, stale-if-error=86400
Cache-Control: public, max-age=60, stale-while-revalidate=30

# Soft purge keeps stale servable during revalidation
curl -X PURGE https://example.com/products/123 -H "Fastly-Soft-Purge: 1"

3. Versioned Keys for Deploys

For static assets, prefer content hashing (app.a3f7c9.js) over purging. When hashing is not possible (HTML, API), use surrogate keys like release-2026-09-12 and purge the previous release key on deploy. This gives you instant, atomic cutover and one-click rollback.

4. Protect Your Origin

Even surgical purges can spike origin if you invalidate a hot key serving 10k RPS. Enable origin shielding, request collapsing, and rate limiting. Consider surrogate-key-based shielding where only one PoP fetches from origin. And always secure your purge endpoint — require token authentication and IP allowlisting. An open purge API is a cache-poisoning vector, which is why proper CDN SSL/TLS configuration and token hygiene matter.

Operational Best Practices

  • Audit every purge: Log who purged what, when, and why. Correlate with hit ratio and origin 5xx dashboards.
  • Test tag emission: Add integration tests that fetch key pages and assert Surrogate-Key and Cache-Tag headers are present and correctly formatted.
  • Respect limits: Batch purges (e.g., 30 tags per Cloudflare call, 256 keys per Fastly call) and implement exponential backoff on 429 responses.
  • Avoid purge-all: If you must, do it during low traffic, warm the cache afterward, and alert on origin load.
  • Monitor staleness: Use Age and X-Cache headers to verify purges actually propagated. Synthetic checks should fetch the same URL from multiple regions post-purge.

Conclusion

Instant purge, tag-based purging, and surrogate key purging are not competing options — they are a progression. Start with instant purge for simplicity, add tags when you need group invalidation, and graduate to surrogate keys when your catalog, API surface, or personalization demands high-cardinality, multi-dimensional control. The goal is the same: purge the minimum necessary, as fast as possible, without ever risking origin overload. Implement event-driven soft purges, enforce key hygiene at the origin, and treat your purge pipeline as critical infrastructure. Done right, cache invalidation stops being a fear and becomes a competitive advantage — fresh content at edge speed, with a 95%+ hit ratio intact.

Frequently Asked Questions

What is the difference between CDN purge and cache invalidation?

Cache invalidation is the general concept of making cached content stale, which can happen via TTL expiry, revalidation, or explicit eviction. A CDN purge is the explicit, API-driven operation that actively removes or marks objects as stale across all edge PoPs before their TTL expires, giving you deterministic control over freshness.

How fast is an instant purge and is it truly global?

On modern CDNs like Fastly, Cloudflare, and Akamai, instant purges propagate via a dedicated global purge bus in 100–300ms to all PoPs. It is effectively global and atomic, but end users may still see stale content if their browser cache or a corporate proxy caches the response separately from the CDN.

When should I use surrogate keys instead of tag-based purging?

Choose surrogate keys when you need high-cardinality and multi-dimensional invalidation — for example, an e-commerce platform where a single API response contains 40 products and each product appears on dozens of pages. Surrogate keys support thousands of keys per object and atomic multi-key purges, while basic tag-based purging is limited to ~128 tags per object and is better for simpler group invalidation.

Does purging affect CDN cache hit ratio and origin load?

Yes. Every purge is a hit-ratio trade-off. A surgical surrogate-key purge that invalidates 0.1% of your cache preserves overall hit ratio, while a purge-all drops it to zero and can cause a thundering herd that overwhelms origin. Use soft purges, origin shielding, and stale-while-revalidate to minimize origin impact.

References & Standards: W3C Web Performance · Cloudflare documentation