/cdn-caching
Debug Vercel CDN caching — cache hit rate, stale content, revalidation behavior, ISR + PPR, per-request cache reasons (cacheReason) and PPR state (ppr_state), and costs.
$ npx -y skills add vercel-labs/vercel-plugin --skill cdn-caching --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/cdn-caching
Context preview
The summary Claude sees to decide when to auto-load this skill.
Debug Vercel CDN caching — cache hit rate, stale content, revalidation behavior, ISR + PPR, per-request cache reasons (cacheReason) and PPR state (ppr_state), and costs.
SKILL.md
cdn-caching.SKILL.mdname: cdn-caching
description: Debug Vercel CDN caching — cache hit rate, stale content, revalidation behavior, ISR + PPR, per-request cache reasons (cacheReason) and PPR state (ppr_state), and costs.
metadata:
priority: 6
docs:
- 'https://vercel.com/docs/caching'
- 'https://vercel.com/docs/caching/cdn-cache'
- 'https://vercel.com/docs/incremental-static-regeneration'
- 'https://vercel.com/docs/cli/metrics'
bashPatterns:
- '\bvercel\s+cache\s+(purge|invalidate|dangerously-delete)\b'
promptSignals:
phrases:
- 'cache hit rate'
- 'isr cost'
- 'isr read units'
- 'isr write units'
- 'stale content'
- 'x-vercel-cache'
- 'cache reason'
- 'cacheReason'
- 'x-vercel-cache-reason'
- 'ppr state'
- 'ppr_state'
- 'x-vercel-ppr-state'
- 'stale_time'
- 'stale_tag'
- 'stale_error'
- 'draft_mode'
- 'prerender_bypass'
allOf:
- [cache, debug]
- [stale, cache]
- [revalidation, count]
- [cache, reason]
- [why, stale]
- [why, bypass]
- [cache, miss]
anyOf:
- 'revalidate'
- 'prerender'
- 'invalidate'
- 'draft mode'
- 'crawler'
- 'cold cache'
- 'request collapsed'
minScore: 6
retrieval:
aliases:
- cache reason
- ppr state
- cache hit rate
- stale content
intents:
- why is my page stale
- why is this request a bypass
- why was this a cache miss
entities:
- cacheReason
- ppr_state
- collapsed
- draft_mode
- prerender_bypass
- stale_time
- stale_tag
- stale_error
chainTo:
-
pattern: 'use cache|cacheLife|cacheTag'
targetSkill: next-cache-components
message: 'Next.js cache directives detected — loading Cache Components guidance for revalidate/tag tuning.'Vercel Caching
You are an expert in understanding Vercel's caching infrastructure, and how the CDN Cache, ISR, and PPR work.
Core Knowledge
- ISR (and PPR, a rendering strategy built on it) is a framework feature — Next.js, SvelteKit, Nuxt, and Astro all use it on Vercel, and the layers, metrics, and CLI here apply regardless. (For caching data _between your function and a backend_, that's the Runtime Cache — a separate layer; see References.)
- **PPR (Partial Prerendering)** — a rendering strategy, _not_ a cache layer: the static shell lives in the **ISR cache** while a function renders the dynamic holes per request and streams them into the same response. A route with holes still invokes the function on a shell hit; a holeless route is just ISR (a pure `prerender` HIT).
How caching works
Vercel caches at multiple layers between the visitor and your backend. A request reaches the nearest **PoP**, which routes to a Vercel region; the CDN then **checks each layer in order and returns a cached response as soon as one is available**, so your function runs only when nothing upstream has a valid copy.
Cache layers
- **CDN cache** — regional, ephemeral. On a hit the region returns the response with no function call. Reads/writes are **free**.
- **ISR cache** — durable, in a single [Function region](https://vercel.com/docs/functions/configuring-functions/region). On a CDN miss, Vercel reads here _before_ invoking your function (cache shielding), then replicates the result back to the CDN. Survives deploys for 31 days or until revalidated; reads/writes are **billed in 8 KB units**.
- **Function invocation** — runs only if neither cache has a valid copy. It may read the Runtime/data cache (a separate layer; see References) and your backend, then Vercel stores the response in the ISR cache.
- **Image cache** — optimized images, cached on the CDN after the first transform.
- Purges propagate globally in ~300 ms.
**Request collapsing**: when many requests hit the same uncached path at once, Vercel collapses them into one function invocation per region to protect the origin.
Key concepts
- **Cache hit rate** — share served from cache (`HIT`/`STALE`/`PRERENDER`) versus origin (`MISS`/`REVALIDATED`). Measure it over _cacheable_ requests — exclude `BYPASS` and `(not set)` (redirects, errors, uncacheable methods), or they drag the ratio down for non-cache reasons. Low hit rate means more origin load and higher latency.
- **Revalidation** — refreshing cached content. **Time-based** runs automatically after an interval; **on-demand** runs when you call an API. Both use stale-while-revalidate: visitors keep getting the cached version while the new one regenerates in the background.
- **Invalidate vs. dangerously-delete** — two ways to clear content, with very different blast on hit rate:
- _Invalidate_ (`invalidateByTag`, Next.js `revalidateTag`/`revalidatePath`) = stale-while-revalidate. Keeps serving stale while refreshing in the background → response shows `x-vercel-cache: STALE`.
- _Dangerously-delete_ (`dangerouslyDeleteByTag`, Next.js `updateTag` or a revalidate with no lifetime) = hard removal. The next request blocks in the **foreground** to regenerate → `x-vercel-cache: REVALIDATED`.
- **Cache tags & blast radius** — tags group cached entries so one call can clear many. A coarse tag attached to thousands of paths has a large _blast radius_: a single write drops them all and the hit rate collapses until they re-warm. Prefer granular tags (`product-${id}`) plus a roll-up tag.
- **Cache status** (`x-vercel-cache` response header) — the _outcome_:
| Value | Meaning | | ------------- | ---------------------------------------------------------------- | | `HIT` | Served from cache; no function ran | | `MISS` | Not cached; origin/function ran | | `STALE` | Served stale while revalidating in background (SWR / invalidate) | | `PRERENDER` | Served a prerendered ISR/PPR shell
Read more
name: cdn-caching
description: Debug Vercel CDN caching — cache hit rate, stale content, revalidation behavior, ISR + PPR, per-request cache reasons (cacheReason) and PPR state (ppr_state), and costs.
metadata:
priority: 6
docs:
- 'https://vercel.com/docs/caching'
- 'https://vercel.com/docs/caching/cdn-cache'
- 'https://vercel.com/docs/incremental-static-regeneration'
- 'https://vercel.com/docs/cli/metrics'
bashPatterns:
- '\bvercel\s+cache\s+(purge|invalidate|dangerously-delete)\b'
promptSignals:
phrases:
- 'cache hit rate'
- 'isr cost'
- 'isr read units'
- 'isr write units'
- 'stale content'
- 'x-vercel-cache'
- 'cache reason'
- 'cacheReason'
- 'x-vercel-cache-reason'
- 'ppr state'
- 'ppr_state'
- 'x-vercel-ppr-state'
- 'stale_time'
- 'stale_tag'
- 'stale_error'
- 'draft_mode'
- 'prerender_bypass'
allOf:
- [cache, debug]
- [stale, cache]
- [revalidation, count]
- [cache, reason]
- [why, stale]
- [why, bypass]
- [cache, miss]
anyOf:
- 'revalidate'
- 'prerender'
- 'invalidate'
- 'draft mode'
- 'crawler'
- 'cold cache'
- 'request collapsed'
minScore: 6
retrieval:
aliases:
- cache reason
- ppr state
- cache hit rate
- stale content
intents:
- why is my page stale
- why is this request a bypass
- why was this a cache miss
entities:
- cacheReason
- ppr_state
- collapsed
- draft_mode
- prerender_bypass
- stale_time
- stale_tag
- stale_error
chainTo:
-
pattern: 'use cache|cacheLife|cacheTag'
targetSkill: next-cache-components
message: 'Next.js cache directives detected — loading Cache Components guidance for revalidate/tag tuning.'Vercel Caching
You are an expert in understanding Vercel's caching infrastructure, and how the CDN Cache, ISR, and PPR work.
Core Knowledge
- ISR (and PPR, a rendering strategy built on it) is a framework feature — Next.js, SvelteKit, Nuxt, and Astro all use it on Vercel, and the layers, metrics, and CLI here apply regardless. (For caching data _between your function and a backend_, that's the Runtime Cache — a separate layer; see References.)
- **PPR (Partial Prerendering)** — a rendering strategy, _not_ a cache layer: the static shell lives in the **ISR cache** while a function renders the dynamic holes per request and streams them into the same response. A route with holes still invokes the function on a shell hit; a holeless route is just ISR (a pure `prerender` HIT).
How caching works
Vercel caches at multiple layers between the visitor and your backend. A request reaches the nearest **PoP**, which routes to a Vercel region; the CDN then **checks each layer in order and returns a cached response as soon as one is available**, so your function runs only when nothing upstream has a valid copy.
Cache layers
- **CDN cache** — regional, ephemeral. On a hit the region returns the response with no function call. Reads/writes are **free**.
- **ISR cache** — durable, in a single [Function region](https://vercel.com/docs/functions/configuring-functions/region). On a CDN miss, Vercel reads here _before_ invoking your function (cache shielding), then replicates the result back to the CDN. Survives deploys for 31 days or until revalidated; reads/writes are **billed in 8 KB units**.
- **Function invocation** — runs only if neither cache has a valid copy. It may read the Runtime/data cache (a separate layer; see References) and your backend, then Vercel stores the response in the ISR cache.
- **Image cache** — optimized images, cached on the CDN after the first transform.
- Purges propagate globally in ~300 ms.
**Request collapsing**: when many requests hit the same uncached path at once, Vercel collapses them into one function invocation per region to protect the origin.
Key concepts
- **Cache hit rate** — share served from cache (`HIT`/`STALE`/`PRERENDER`) versus origin (`MISS`/`REVALIDATED`). Measure it over _cacheable_ requests — exclude `BYPASS` and `(not set)` (redirects, errors, uncacheable methods), or they drag the ratio down for non-cache reasons. Low hit rate means more origin load and higher latency.
- **Revalidation** — refreshing cached content. **Time-based** runs automatically after an interval; **on-demand** runs when you call an API. Both use stale-while-revalidate: visitors keep getting the cached version while the new one regenerates in the background.
- **Invalidate vs. dangerously-delete** — two ways to clear content, with very different blast on hit rate:
- _Invalidate_ (`invalidateByTag`, Next.js `revalidateTag`/`revalidatePath`) = stale-while-revalidate. Keeps serving stale while refreshing in the background → response shows `x-vercel-cache: STALE`.
- _Dangerously-delete_ (`dangerouslyDeleteByTag`, Next.js `updateTag` or a revalidate with no lifetime) = hard removal. The next request blocks in the **foreground** to regenerate → `x-vercel-cache: REVALIDATED`.
- **Cache tags & blast radius** — tags group cached entries so one call can clear many. A coarse tag attached to thousands of paths has a large _blast radius_: a single write drops them all and the hit rate collapses until they re-warm. Prefer granular tags (`product-${id}`) plus a roll-up tag.
- **Cache status** (`x-vercel-cache` response header) — the _outcome_:
| Value | Meaning | | ------------- | ---------------------------------------------------------------- | | `HIT` | Served from cache; no function ran | | `MISS` | Not cached; origin/function ran | | `STALE` | Served stale while revalidating in background (SWR / invalidate) | | `PRERENDER` | Served a prerendered ISR/PPR shell
Comprehensive Vercel ecosystem plugin — relational knowledge graph, skills for every major product, specialized agents, and Vercel conventions. Turns any AI agent into a Vercel expert.
Repo: vercel-labs/vercel-plugin
Other skills on vercel.
- /benchmark-agents
Advanced AI agent benchmark scenarios that push Vercel's cutting-edge platform features — Workflow DevKit, AI Gateway, MCP, Chat SDK, Queues, Flags, Sandbox, and multi-agent orchestration. Designed to stress-test skill injection for complex, multi-system builds.
Open skill - /benchmark-e2e
End-to-end benchmark suite for vercel-plugin. Runs realistic projects through skill injection, launches dev servers, verifies everything works, analyzes conversation logs, and produces an improvement report for overnight self-improvement loops.
Open skill - /benchmark-sandbox
Run vercel-plugin eval scenarios in Vercel Sandboxes instead of local WezTerm panels. Provisions ephemeral microVMs with Claude Code + plugin pre-installed, runs benchmark prompts, extracts hook artifacts, and produces coverage reports.
Open skill - /benchmark-testing
Create and launch benchmark test projects to exercise vercel-plugin skill injection across realistic scenarios. Sets up isolated directories, installs the plugin, and spawns WezTerm panes running Claude Code with crafted prompts.
Open skill - /plugin-audit
Audit vercel-plugin performance on real-world projects. Extracts tool calls from Claude Code conversation logs, tests hook matching against actual inputs, identifies pattern coverage gaps, and checks plugin cache staleness. Use when asked to audit, test, or investigate plugin
Open skill - /release
Release vercel-plugin — run gates, bump version, generate artifacts, commit, and push. Use when asked to "release", "ship", "bump and push", or "cut a release".
Open skill

