Revalidation and purging
Refresh or invalidate CDN and Runtime Cache content before its lifetime ends.
Cached content stays until its lifetime ends. To refresh it sooner, tag it and
invalidate the tag, revalidate a framework path, or purge the production cache
from the dashboard. Lifetimes and stale-while-revalidate are covered in
Caching.
Choose an approach
| Goal | Approach |
|---|---|
| Refresh on a fixed interval | Set s-maxage, optionally with stale-while-revalidate |
| Invalidate related content across many URLs | Cache tags |
| Refresh one framework route | revalidatePath |
| Clear everything for production | Purge cache in the dashboard |
| Invalidate values inside your function | Runtime Cache tags |
Invalidating marks entries as no longer fresh. The next matching request is a
MISS that regenerates the response, and the one after that is a HIT.
Invalidation doesn't produce the new content itself.
Cache tags
A tag groups cached entries so one call invalidates all of them, without
knowing every affected URL. One product update might touch /products,
/products/widget, /api/products/widget, and a cached database query. Tag
each with product:widget and invalidate them together.
Add tags to a cacheable response with any of these headers. Easel reads all three and accepts commas or spaces as separators:
Next.js emits x-next-cache-tags for you when you use cacheTag or fetch
tags.
Tag naming
Use stable type:id names such as product:123, article:842, or
organization:acme. Add a broad tag alongside the specific one when an update
can affect a list as well as an item:
Don't put timestamps, request or session IDs, random values, or unbounded user
input in tags. Scope tags to the narrowest owner, such as
organization:acme, rather than a global tag when an update affects one
customer.
Invalidate a tag
Next.js
revalidateTag and revalidatePath invalidate the matching CDN entries,
framework cache entries, and Runtime Cache entries together:
Tag fetched data with next: { tags: ["product:123"] } or cacheTag. See
Next.js.
Runtime Cache
From any framework, expireTag removes Runtime Cache entries with the tag and
invalidates CDN responses that carry the same tag. Tags are one namespace
across Easel's caches, and expiry reaches every region, typically well under a
second:
Use one tag on both the rendered response and the data it was built from, so a regenerated page doesn't read stale data. See Runtime Cache.
Other frameworks get CDN behavior from the cache headers and tag headers their adapters emit. See the framework guides.
Purge the production cache
On the project overview, open the production actions menu and choose Purge cache. It clears the production deployment's cached pages and Runtime Cache entries, and pages render fresh on their next request.
Purge everything only when a tag won't do. A full purge drops your hit rate and makes many routes regenerate at once.
Easel doesn't offer purging a single URL. Use a tag or revalidatePath.
Scope
CDN and ISR entries belong to one deployment, so invalidating production doesn't touch preview deployments, and a new deployment starts with an empty CDN cache. Runtime Cache is shared by the deployments in an environment, so expiring a tag reaches every Runtime Cache entry with that tag in that environment's cache. On Hobby, that cache is shared by every project in the workspace.
Update before you invalidate
Update the source of truth, confirm it succeeded, then invalidate. If you invalidate first, a request that arrives in between regenerates the page from the old data and caches it again.
Browser caches
Invalidation clears Easel's cache, not copies already in visitors' browsers.
With Cache-Control: public, max-age=3600, a browser keeps showing its copy for
up to an hour. Put the CDN lifetime in s-maxage or CDN-Cache-Control so
browsers revalidate on each visit. See
Caching.
Tags don't replace privacy directives. Mark user-specific responses
Cache-Control: private, no-store so they're never shared.