Tutorial · cloudflare · Published 2026-08-16 · 4 min read
Purge Cloudflare cache by cache tags
Purge Cloudflare cache by tags: add Cache-Tag headers at the origin, then issue one purge call that clears every asset carrying that tag.
What a cache tag is
A cache tag is a name you attach to a group of edge-cached responses so one purge invalidates the whole group. Where a plain purge clears exact URLs or a prefix, a tag follows the concept instead: every response wearing the release-news tag is removed from the edge when you push a purge for release-news, whether those responses live under /blog/, under /assets/css/, or on another hostname in the zone.
Tags match the architecture of a deploy. When you ship a release, the pages and assets that changed usually share a reason, the release. Tagging release-2026-08-v3 at generation time means a failed or rolled-back deploy is one API call to reverse, not a script that re-walks every changed URL.
The rules the tag must obey
Cloudflare reads the tag from the Cache-Tag response header the origin returns:
- The header value is a comma-separated list:
Cache-Tag: faq, style-css-prod. - Individual tags have no length limit at the edge, but the combined header value cannot exceed 16 KB, which is roughly 1,000 unique tags on one response.
- Printable ASCII only, no spaces, no Unicode; matching is case-insensitive.
- For the purge API call itself, each tag in the request body is limited to 1,024 characters.
- The header is stripped before the response reaches the visitor. End users never see it; it exists only to label the cached entry.
Any response you want to tag must be cacheable by the edge in the first place, the same cache rules and TTL logic that decides what the dynamic-content caching article covers.
Add the header at the origin
The tag must be emitted by the origin response, because Cloudflare reads it as the response arrives from the server:
Header set Cache-Tag "prone-page, release-2022-06-v21"
For a PHP or serverless origin, set it in the response headers you return:
header('Cache-Tag: faq, release-2022-06-v21');
In a Workers front end, set the extra header on the response you hand back from fetch():
export default {
async fetch(request) {
const url = new URL(request.url);
const upstream = await fetch(request);
const headers = new Headers(upstream.headers);
const tag = url.pathname.startsWith('/blog/') ? "blog-common" : "faq";
headers.set("Cache-Tag", tag);
return new Response(upstream.body, { status: upstream.status, headers });
},
};
Do not try to fake a CF-Cache-Status value yourself: Cloudflare sets that header on the cached path and it is a status signal, not something the origin or a Worker should write. For a WordPress or static site that cannot set response headers from the app, a Response Header Transform Rule can set Cache-Tag on your behalf so the origin does not need any code change (Transform Rules add the header to the response before it re-enters the cache path).
Purge by tag
In the dashboard
Open Caching > Configuration > Purge Cache and choose Custom Purge. Set the method to Tag and enter the tags, comma-separated or one per line. The purge forces a cache MISS on every response wearing the tag, and the next visitor to any of those URLs re-fetches from the origin.
With the API
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
-H "Authorization: Bearer ${CF_TOKEN}" \
-H "Content-Type: application/json" \
--data '{"tags":["release-2022-06-v21","prisma-page"]}'
The API token needs the Cache Purge permission for the zone, on the same plan tier that governs purge limits. Free accounts can purge by tag; the shared per-account request rate (5 requests per minute with a burst bucket of 25) still applies.
Reasoning that belongs in the plan, not in the click
- Tag purge does not touch stale state; it invalidates and lets the edge re-fetch. Test the tag name matches what you actually write in the header, and that the affected URL was cacheable at all.
- Use distinct tags per release or batch so a staged release does not purge a neighbouring feature by accident. When one deploy changes both the site pages and its shared assets, two tags in one API call invalidate each group without entangling them.
- Keep the header flowing with a response-header transform when the origin is a managed service you cannot edit. The transform is part of the same dashboard you already use for the cache TTL rules.
A deploy that pivots on one tag means rollback stops being a job someone has to reverse-engineer at 2am. It is still just a cache invalidation. The header works because it is declarative and every release can be its own tag, so your cache purge and your release name become the same noun.