Skip to main content
CDN

Invalidate and revalidate cached content

Expire CDN responses, Runtime Cache entries, and framework page caches by tag.

When you purge by cache tag, Easel updates the shared platform tag clock and invalidates matching edge CDN entries for the deployment. Runtime Cache entries and Incremental Static Regeneration (ISR) pages that carry those tags become stale as well. That matches Vercel’s multi-layer purge model.

Time-based CDN lifetime still follows response headers. See Cache responses at the edge.

Cache tags

Cache tags are strings you attach to cached responses or Runtime Cache entries. Use them when one piece of content appears on many URLs (for example product-123 on overview and reviews pages).

Tags are case-sensitive. Do not put commas inside a tag; commas separate tags in headers and APIs.

Add tags to a response

Attach the same tag string to CDN responses (and optionally Runtime Cache writes) so you can expire them later:

app/api/product/route.ts
import { cacheTag } from "next/cache";

export async function GET(request: Request) {
  const id = new URL(request.url).searchParams.get("id") ?? "unknown";
  cacheTag(`product-${id}`, "products");

  const product = await loadProduct(id);
  return Response.json(product, {
    headers: {
      "CDN-Cache-Control": "public, s-maxage=86400",
      "Cache-Tag": `product-${id},products`,
    },
  });
}

Easel indexes Cache-Tag, x-next-cache-tags, and surrogate-key. See Runtime Cache for tagged getCache() writes.

Expire tags from your app

app/actions.ts
"use server";

import { revalidatePath, revalidateTag } from "next/cache";

export async function publishProduct(id: string) {
  await saveProduct(id);
  revalidateTag(`product-${id}`);
  revalidateTag("products");
  revalidatePath(`/products/${id}`);
}

Easel records durable tag expiry, refreshes ISR on the next hit, removes matching Runtime Cache entries when you use expireTag, and purges edge CDN bodies for the deployment.

Schedule work after the response

app/api/publish/route.ts
import { after } from "next/server";
import { revalidateTag } from "next/cache";

export async function POST() {
  after(() => {
    revalidateTag("products");
  });
  return Response.json({ ok: true });
}

Keep background work inside the platform’s per-request drain limit.

Choose a path

GoalApproach
Cache any HTTP response at the edgeCache headers (Caching)
Expire many CDN URLs for one entityCache-Tag + revalidateTag / expireTag
Share values across function isolatesRuntime Cache
Refresh Next.js ISR HTMLrevalidatePath and/or revalidateTag