Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions skills/cdn-caching/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,15 @@ 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** (`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 states:

| `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 |
| `ppr_state` | Meaning |
| ----------- | ------------------------------------------------------------------------------------ |
| Static | Fully prerendered — no postponed state, so the function is not invoked for the body |
| Partial | A static shell serves from cache + a postponed hole the function resumes per request |
| Dynamic | 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`.
A **Partial** serve that still invokes the function is _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

Expand Down
Loading