---
title: "Cache Invalidation for CDNs: TTLs, Purges, and Origin Shield"
description: "Cache invalidation for CDNs explained: set TTLs, choose targeted purges, prevent origin stampedes, verify freshness, and protect media delivery globally."
url: https://www.zerobuffer.io/blogs/cache-invalidation
date_published: 2026-08-18
date_modified: 2026-08-18
topic: "CDN Caching & Performance"
keywords: ["cache invalidation","cache ttl","origin shield","cloudfront invalidation","cache hit","cache hit rate","cloud flare cache"]
word_count: 2607
author: "Sahil Asopa"
author_url: https://www.zerobuffer.io/authors/sahil-asopa
author_profiles: ["https://www.linkedin.com/in/sahilasopa/","https://github.com/sahilasopa"]
publisher: ZeroBuffer
license: © 2026 Apexnova Private Limited
---
![Distributed CDN cache nodes refresh safely without overwhelming the origin](https://www.zerobuffer.io/blogs/cache-invalidation/thumbnail.png)

# Cache Invalidation for CDNs: TTLs, Purges, and Origin Shield

A release is live at the origin, yet one region still serves the old bundle. A corrected video manifest reaches some viewers but not others. Then a global purge fixes freshness and creates a wall of cache misses that overloads the packager. These are **cache invalidation** failures, even when the purge API itself returns success.

**Cache invalidation is the process of making a cached response unusable before it would naturally expire, so the next request revalidates or fetches a fresh copy from the origin. For CDNs, the safest strategy combines versioned URLs, explicit cache TTLs, targeted purges, and a protected origin instead of relying on “purge everything.”**

This guide gives platform, DevOps, and media teams a practical way to choose those controls, verify the result, and keep a freshness fix from becoming an availability incident.

## What cache invalidation actually changes

A CDN stores copies of origin responses at distributed edge locations. Each cached object has a cache key, a freshness lifetime, and usually a validator such as an `ETag` or `Last-Modified` value. Invalidation changes whether an existing copy can satisfy another request; it does not change the source object.

The distinction matters operationally:

- **Expiration** happens when the object's cache TTL runs out.
- **Revalidation** asks the origin whether a stale copy is still current, often with `If-None-Match` or `If-Modified-Since`.
- **Invalidation or purge** tells CDN caches not to use selected copies before normal expiration.
- **Eviction** is automatic removal, often because cache capacity is needed for other objects.

Provider terminology is inconsistent. One platform may call deletion a purge and another may call the same control an invalidation. Treat the observable behavior—not the button label—as the contract: can stale bytes still be served, does the next request block, and which cache layers and variants are affected?

Google Cloud's [cache invalidation overview](https://docs.cloud.google.com/cdn/docs/cache-invalidation-overview) adds a crucial boundary: a CDN invalidation does not clear copies already stored in browsers or third-party intermediary caches. AWS therefore recommends versioned filenames for frequently updated assets because a new URL also bypasses those old downstream copies ([CloudFront invalidation guidance](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html)).

## Choose a cache invalidation strategy by freshness budget

Start with one question: **How long may this response be wrong?** The answer is a freshness budget, and it should be set per content class rather than once for the entire hostname.

| Content class | Tolerable staleness | Default mechanism | Emergency mechanism |
|---|---:|---|---|
| Hashed JavaScript, CSS, images, VOD segments | Until references change | Versioned URL plus long TTL | Remove the reference; purge only for unsafe content |
| Product page or public API | Seconds to minutes | Short shared TTL plus revalidation | URL or tag purge |
| Homepage, article, catalog collection | A few minutes | Moderate TTL plus event-driven tag purge | Prefix or tag purge |
| Live HLS/DASH manifest | One or a few manifest cycles | Very short TTL aligned to update cadence | Targeted manifest purge |
| Revoked, private, or legally sensitive object | None | Do not shared-cache, or use tightly scoped access | Hard purge every relevant variant and revoke access |

This prevents two common extremes. A very short TTL on everything protects freshness but destroys cache hit rate and keeps the origin busy. A long TTL with no reliable invalidation makes normal publishing depend on emergency purges.

Use four mechanisms together:

1. **Version immutable objects.** Put a content hash or release ID in the URL and give the object a long cache TTL.
2. **Bound staleness with TTLs.** A failed event or missed purge must still self-correct within an acceptable window.
3. **Purge mutable objects precisely.** Target a URL, cache tag, hostname, or prefix that maps to the changed dependency.
4. **Protect refills.** Request collapsing, stale serving, and an origin shield reduce the load created when many edges need the same fresh object.

The right design is hybrid. TTL is the safety net, not the deployment system; purge is the exception path, not the only freshness model.

## Cache TTL and HTTP headers: define the freshness contract

The origin should express cache intent explicitly. Under [RFC 9111](https://www.rfc-editor.org/rfc/rfc9111.html), `max-age` defines when a response becomes stale, while `s-maxage` can override that lifetime in a shared cache such as a CDN.

For a public page that may be one minute out of date at the edge but should revalidate quickly, a starting policy might be:

```http
Cache-Control: public, max-age=60, stale-while-revalidate=30
ETag: "page-7f3a"
```

Here a supporting cache can consider the response fresh for 60 seconds, then serve it stale for another 30 seconds while refreshing it. The `stale-while-revalidate` behavior is defined in [RFC 5861](https://www.rfc-editor.org/rfc/rfc5861.html), but implementations and maximum TTL rules vary by CDN. If browser and edge lifetimes must differ, use a tested shared-cache directive, CDN-specific response header, or edge rule rather than assuming every provider combines directives identically.

The important directives are easy to confuse:

- `max-age=N` sets a freshness lifetime for caches generally.
- `s-maxage=N` sets the shared-cache lifetime and overrides `max-age` there.
- `no-cache` permits storage but requires validation before reuse.
- `no-store` says the response must not be stored by a cache.
- `must-revalidate` prohibits reuse of a stale response without successful validation.
- `stale-while-revalidate=N` permits bounded stale serving during an asynchronous refresh.
- `stale-if-error=N` can preserve availability when revalidation hits an origin error.

Validators make expiry cheaper. A matching `ETag` lets the origin return `304 Not Modified` instead of sending the whole payload again; the internal [ETag guide](/blogs/what-is-e-tag) covers that handshake. Validators do not replace TTLs or invalidation events—they reduce the cost of checking.

### Do not copy one TTL across every media object

Media delivery exposes bad defaults quickly. A live playlist changes repeatedly and needs a short cache TTL. Completed VOD segments are effectively immutable and can use a long TTL when their URLs change with the content. Signing keys, entitlements, and personalized API responses need separate policies and often must bypass shared caching entirely.

The internal [CDN vs caching guide](/blogs/cdn-vs-caching) explains where browser, edge, and origin-side caches differ. Define a policy for each layer; otherwise the CDN may refresh correctly while an upstream reverse proxy or browser continues serving the old response.

## Cache invalidation methods: URL, tags, prefixes, and versions

Choose the narrowest control that covers every affected object.

### Versioned URLs for routine deployments

For static assets, publish `app.7f3a.js` instead of overwriting `app.js`. Deploy the new asset first, then update the HTML or manifest that references it. The new URL is a natural cache miss, the old release remains available during rollback, and no global purge is required.

Use long-lived `immutable` caching only when the URL truly changes with the bytes. Reusing an “immutable” URL for different content creates a stale-copy problem that CDN invalidation cannot reliably fix in browser caches.

### URL purge for one known object

Purge a specific URL when one canonical object changed unexpectedly or must disappear now. This is easier to audit than a wildcard and limits the refill blast radius.

The cache key can complicate the target. If language, device type, query parameters, cookies, or headers create variants, verify whether a URL purge removes all variants or requires the same key inputs. Cloudflare's [purge API documentation](https://developers.cloudflare.com/api/resources/cache/methods/purge/) shows, for example, that custom cache-key headers may need to accompany a single-file purge.

### Cache tags for dependency-aware invalidation

One content change often affects many URLs: a product appears on its detail page, category page, recommendations, and homepage. Cache tags—also called surrogate keys—attach semantic dependencies such as `product:724253` or `release:2026-08-18` to every related response. One event can then invalidate the group without listing URLs or clearing the entire service.

[Google Cloud CDN](https://docs.cloud.google.com/cdn/docs/cache-invalidation-overview#invalidation_by_cache_tags), [Cloudflare](https://developers.cloudflare.com/cache/how-to/purge-cache/), [Fastly](https://www.fastly.com/documentation/guides/full-site-delivery/purging/purging-with-surrogate-keys/), and [CloudFront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/invalidation-by-tags.html) all document tag-oriented invalidation, though header names, limits, and semantics differ. Fastly also supports soft purging, which marks content stale rather than immediately discarding it.

Design tags as part of the data model. Centralize tag generation, keep names stable, and record which write events must emit which tags. If tagging is an afterthought, missing dependencies become intermittent stale pages.

### Prefix, hostname, and purge-all controls

A prefix purge is reasonable for an isolated release path such as `/assets/release-42/*`. A hostname purge can be useful when one tenant or environment maps cleanly to a host. “Purge everything” should be reserved for a true service-wide integrity event.

Cloudflare recommends single-file purging even though URL, hostname, tag, prefix, and full-cache options are available ([Cloudflare purge documentation](https://developers.cloudflare.com/cache/how-to/purge-cache/)). Google warns that invalidating too much can suddenly move previously cached traffic to instances or storage buckets ([Cloud CDN best practices](https://docs.cloud.google.com/cdn/docs/cache-invalidation-overview#best_practices)). Precision is an availability control, not merely an API preference.

![A layered CDN invalidation workflow uses cache tags, stale revalidation, and origin shield](https://www.zerobuffer.io/blogs/cache-invalidation/mid-article.png)

## Build a cache invalidation workflow that protects the origin

An invalidation event is not complete when the API accepts it. It is complete when the intended variants are fresh across representative regions and the origin remains healthy.

Use this deployment sequence:

1. **Write the new source object first.** Confirm the origin returns the intended bytes and headers before invalidating anything.
2. **Emit an idempotent invalidation event.** Include the content ID, version, affected tags or URLs, reason, actor, and deployment ID.
3. **Purge the smallest complete set.** Retry safely on transient errors and record the provider's request ID.
4. **Control cache refill.** Keep stale serving within the freshness budget, collapse duplicate misses, and shield the origin.
5. **Verify from the outside.** Check body version, `Age`, `ETag`, cache-status headers, and latency from more than one region.
6. **Watch origin saturation.** Alert on miss rate, origin requests, 5xx responses, packager latency, and egress immediately after the purge.
7. **Preserve rollback.** A versioned prior asset or manifest lets traffic move back without trying to reconstruct a deleted cache state.

Origin shield is particularly useful during the refill. AWS describes CloudFront Origin Shield as an additional cache layer that can consolidate simultaneous requests for the same object into as few as one origin request ([AWS Origin Shield documentation](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/origin-shield.html)). It does not correct the wrong object by itself; your purge and cache-key design still must cover the shield and edge layers used by the request path.

This is where a CDN's operating model matters more than its headline POP count. [ZeroBuffer's OTT delivery stack](/cdn-for-ott) combines configurable cache behavior with origin shield for manifests and segments, while [its homepage](/) documents instant cache purge. For teams with media-heavy traffic, those controls sit alongside flat delivery pricing from $0.0049/GB ([ZeroBuffer pricing](/pricing)), so the freshness plan and the refill bill can be evaluated together.

### Add jitter and warm only what matters

If thousands of objects share the same TTL, they can expire together even without a purge. Add small random TTL variation where exact expiry is not required. After a broad release, pre-warm only the small set of latency-critical objects; crawling the whole catalog can reproduce the origin spike you were trying to avoid.

For live or on-demand video, warm the top manifest and current segments through the same signed, normalized request path viewers use. Warming a different query string or header variant fills a different cache key and provides false confidence.

## Verify cache invalidation instead of trusting the control plane

Create an automated canary object whose body contains a deployment ID. Update it through the normal publishing path, trigger the same invalidation event, and fetch it from multiple regions until every sample returns the new ID.

A simple inspection request should capture headers and body separately:

```bash
curl -sS -D response-headers.txt \
  -o response-body.txt \
  "https://cdn.example.com/cache-canary.json?probe=known-key"
```

Inspect at least:

- the response's release or content ID;
- `Age`, which should reset or reflect the expected cache path;
- `ETag` or `Last-Modified`;
- the provider's `HIT`, `MISS`, `BYPASS`, `STALE`, or revalidation header;
- `Cache-Control` as delivered to the client;
- p95 response time and the corresponding origin request.

Use the internal [cache header checker](/tools/cache-header-checker) for a quick external view, then put deterministic assertions in CI and post-deploy monitoring. A purge test should fail if the old body remains, if only one region refreshes, or if the origin error rate crosses its safe threshold.

### Diagnose “the purge succeeded but content is still stale”

Work through the request path in order:

1. Fetch the origin directly with the correct host header. If it is stale there, the CDN is not the cause.
2. Compare the exact URL, query string, normalized headers, cookies, encoding, device, and geography that form the cache key.
3. Check browser, service-worker, reverse-proxy, application, shield, and edge caches separately.
4. Confirm redirects and URL rewrites did not change the path targeted by the purge.
5. Verify the purge affected the production service, tenant, hostname, and environment.
6. Look for a race in which a stale origin or shield refilled the edge immediately after invalidation.
7. Confirm propagation from several regions instead of relying on one successful request.

Cache hit rate is useful context, not proof of freshness. A high cache hit rate can mean users are receiving the wrong object efficiently. Pair hit ratio with version correctness, cache age, origin load, and purge verification.

## Frequently asked questions

### What is cache invalidation?

Cache invalidation makes a stored response unusable before its normal expiration so a cache must revalidate it or fetch a fresh version. In a CDN, the action may target one URL, a semantic cache tag, a hostname, a prefix, or the entire service.

### Why is cache invalidation hard?

The same logical content can exist in browsers, service workers, edge POPs, shield caches, reverse proxies, and application caches under several cache keys. A correct change has to identify every dependent variant, propagate across distributed nodes, and avoid overwhelming the origin when those nodes refill.

### What is the difference between cache invalidation and cache eviction?

Invalidation is an intentional correctness action: a system or operator declares content stale or removes it. Eviction is automatic cache management, usually caused by expiration or capacity pressure. Never rely on eviction timing to publish an urgent correction.

### Does purging a CDN clear the browser cache?

No. CDN invalidation affects the provider's cache, not copies already stored in user agents or unrelated intermediary caches. Use versioned URLs for static assets, or browser-cache directives and validators that keep downstream staleness within the required budget.

### What cache TTL should I use?

Use the longest TTL that stays within the content's freshness budget and pair it with the appropriate invalidation path. Immutable versioned assets can be cached for a long time; mutable HTML, APIs, and live manifests need shorter, content-specific policies. There is no safe universal TTL for an entire site.

### Can origin shield prevent a cache stampede?

Origin shield can reduce duplicate origin requests by giving edge locations a shared upstream cache and combining requests for the same object. It works best with request collapsing, bounded stale serving, targeted purges, and enough origin capacity for unavoidable cold fills.

## Make freshness an explicit reliability target

Choose invalidation policy by content class and acceptable staleness, not by the easiest CDN button. Version immutable assets, set cache TTLs as a recovery bound, use URL or tag purges for mutable dependencies, and protect the resulting refill through stale revalidation and origin shield.

Then test the entire loop. If your team cannot prove which version a user receives in each region—or predict what a purge will do to the origin—the cache policy is not finished. Start with one high-value content class, define its freshness budget and cache key, automate a targeted invalidation canary, and expand only after the evidence is clean.

Run that canary on a network built for media. ZeroBuffer ships instant cache purge together with origin shielding for manifests and segments across 100+ edge locations, so the freshness fix and the refill it triggers can be observed as one system. Delivery is a flat $0.0049/GB priced by volume rather than geography, which means a cold refill does not arrive as a surprise line on the invoice. [See how the delivery stack is put together](/cdn-for-ott), or [check your current cache headers](/tools/cache-header-checker) first.
