From 67cdc08ab44d0a0ca3657a6284099e2c9063a6c9 Mon Sep 17 00:00:00 2001 From: Shina Patel Date: Fri, 24 Jul 2026 16:01:51 -0700 Subject: [PATCH] [cdn-caching] Add PPR state (ppr_state) to the skill Mirrors the cacheReason treatment: ppr_state in the description, prompt signals (ppr state / ppr_state / x-vercel-ppr-state), retrieval alias + entity, and a PPR state concept table (page/shell/blocking -> Static/ Partial/Dynamic) next to the cache-reason section. Regenerated manifests. Co-Authored-By: Claude Opus 4.8 --- generated/build-from-skills.manifest.json | 2 +- generated/skill-manifest.json | 7 ++++++- skills/cdn-caching/SKILL.md | 17 ++++++++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/generated/build-from-skills.manifest.json b/generated/build-from-skills.manifest.json index 101a605..bfd7e1b 100644 --- a/generated/build-from-skills.manifest.json +++ b/generated/build-from-skills.manifest.json @@ -1,6 +1,6 @@ { "version": 1, - "generatedAt": "2026-07-07T17:26:07.851Z", + "generatedAt": "2026-07-24T23:01:09.007Z", "templates": [ { "template": "agents/ai-architect.md.tmpl", diff --git a/generated/skill-manifest.json b/generated/skill-manifest.json index a5fd420..bfab66c 100644 --- a/generated/skill-manifest.json +++ b/generated/skill-manifest.json @@ -1,5 +1,5 @@ { - "generatedAt": "2026-07-07T17:36:42.694Z", + "generatedAt": "2026-07-24T23:01:08.971Z", "version": 2, "skills": { "ai-gateway": { @@ -887,6 +887,9 @@ "cache reason", "cacheReason", "x-vercel-cache-reason", + "ppr state", + "ppr_state", + "x-vercel-ppr-state", "stale_time", "stale_tag", "stale_error", @@ -938,6 +941,7 @@ "retrieval": { "aliases": [ "cache reason", + "ppr state", "cache hit rate", "stale content" ], @@ -948,6 +952,7 @@ ], "entities": [ "cacheReason", + "ppr_state", "collapsed", "draft_mode", "prerender_bypass", diff --git a/skills/cdn-caching/SKILL.md b/skills/cdn-caching/SKILL.md index ee09fb6..5bbdbbe 100644 --- a/skills/cdn-caching/SKILL.md +++ b/skills/cdn-caching/SKILL.md @@ -1,6 +1,6 @@ --- name: cdn-caching -description: Debug Vercel CDN caching — cache hit rate, stale content, revalidation behavior, ISR + PPR, per-request cache reasons (cacheReason), and costs. +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: @@ -21,6 +21,9 @@ metadata: - 'cache reason' - 'cacheReason' - 'x-vercel-cache-reason' + - 'ppr state' + - 'ppr_state' + - 'x-vercel-ppr-state' - 'stale_time' - 'stale_tag' - 'stale_error' @@ -46,6 +49,7 @@ metadata: retrieval: aliases: - cache reason + - ppr state - cache hit rate - stale content intents: @@ -54,6 +58,7 @@ retrieval: - why was this a cache miss entities: - cacheReason + - ppr_state - collapsed - draft_mode - prerender_bypass @@ -125,6 +130,16 @@ Vercel caches at multiple layers between the visitor and your backend. A request A raw `MISS` with reason `draft_mode` / `prerender_bypass` / `crawler` is **displayed as `BYPASS`** (all usually expected). The three `stale_*` reasons separate a healthy time refresh (`stale_time`) from a broad-tag blast (`stale_tag`) from a failing regen (`stale_error`). Read `cacheReason` from `vercel logs` or the dashboard Logs "Reason" row — the `x-vercel-cache-reason` header is internal-only and not visible via `curl`. +- **PPR state** (`ppr_state`) — for a Partial Prerendering route, _how much_ of the response was prerendered versus computed per request. Only set on `partial_prerender` serves; blank for plain `prerender` / `func` / `static` routes and for cases the proxy can't classify (cold shell miss, `BYPASS`). Three values: + + | `ppr_state` | Shown as | Meaning | + | ----------- | -------- | ----------------------------------------------------------------------------------- | + | `page` | Static | Fully prerendered — no postponed state, so the function is not invoked for the body | + | `shell` | Partial | Non-empty static shell from cache + a postponed hole the function resumes per request | + | `blocking` | Dynamic | Empty shell — the whole body is postponed and rendered by the function per request | + + A shell hit that still invokes the function is `shell` (Partial), _not_ a cache miss — the cached shell serves immediately while the function fills only the dynamic holes. Read `ppr_state` from `vercel logs` or the dashboard Logs panel, or aggregate with `vercel metrics vercel.request.count --group-by ppr_state`. Like `cacheReason`, the `x-vercel-ppr-state` header is internal-only and not visible via `curl`. + ## Investigating cache issues Reach for the Vercel CLI. `vercel metrics` gives aggregate numbers (requires [Observability Plus](https://vercel.com/docs/observability/observability-plus)); `vercel logs` shows per-request behavior.