GioJSdocs
On this page

gio cache explain

Request a URL from a running GioJS server and explain, in plain words, what its X-Gio-Cache header says the cache did.

npx gio cache explain /posts/1
bash
gio cache explain <url-or-path> [--base <url>]

Reference

ParameterTypeDefaultDescription
<url-or-path> (required)string-An absolute http or https URL (https://example.com/blog) is requested as given. A path (/posts/1) is requested from --base, else from the local server. Anything else (posts/1, localhost:3000/) is a usage error.
--base <url>stringlocal serverThe server a path is requested from: an http or https URL such as https://staging.example.com.
-h, --helpboolean-Print the help and exit with 0.

Behavior

The local server is the address it would listen on, resolved like gio dev resolves it: GIO_PORT / PORT / GIO_HOST, the .env files, then gio.toml, with a wildcard host (0.0.0.0, ::) reached on loopback and https when [server.tls] is enabled.

gio cache explain sends one GET without following redirects, prints the status and the X-Gio-Cache value, and explains it:

X-Gio-CacheWhat happened
hit; ttl=NServed from the Rust page cache without touching Node. ttl is the seconds until the entry goes stale.
stale; age=N; revalidatingServed from the cache past its TTL while one background render refreshes it. age is the seconds since it was rendered.
miss; storedRendered by the Node worker and stored; the next request is a hit.
bypassNot served from the cache. Either rendered and not stored - the page has no revalidate, the request was not GET / HEAD, the render was personalized (cookies, credentials, client address), it set per-request headers, or [cache] enabled = false - or refused by the server itself before Node (a rate-limit 429, a skew 409, a CSRF 403).
staticA file from public/, a hashed chunk under /_next/static/ or a self-hosted font under /_gio/fonts/, served by Rust without the cache or Node.
ppr; ...Partial prerendering: the shared shell came from (or went into) the cache and the Suspense holes rendered for this request.
(absent)An internal /_gio endpoint, or a server older than X-Gio-Cache. The image optimizer, /_gio/image, answers HIT or MISS for its own cache instead; the command prints that value as it is.

Examples

Watch a page get cached

text
$ npx gio cache explain /blog
GET http://127.0.0.1:3000/blog
  status       200
  x-gio-cache  miss; stored
  → Rendered by the Node worker and stored in the cache - the next
    request for this key is a hit. Pages opt in via `export const revalidate`.
$ npx gio cache explain /blog
GET http://127.0.0.1:3000/blog
  status       200
  x-gio-cache  hit; ttl=60
  → Served from the Rust page cache without touching Node. "ttl" is the
    seconds until this entry goes stale.

With app/blog/page.tsx exporting revalidate = 60.

A page that is not cached

text
$ npx gio cache explain /about
GET http://127.0.0.1:3000/about
  status       200
  x-gio-cache  bypass
  → NOT served from the cache. Either rendered by the Node worker but not
    stored - the page cache is off (`[cache] enabled = false`), the page did
    not declare `revalidate`, the request was not GET/HEAD, the response
    varies per user, or it set per-request headers - or refused by the
    server itself before Node (a rate-limit 429, a skew 409, a CSRF 403).

When a page declares revalidate but its render is personalized (it read cookies or credentials, or set a cookie), the server logs a warning naming the route.

Ask a deployed server

bash
npx gio cache explain /pricing --base https://staging.example.com
npx gio cache explain https://example.com/pricing

A local server on another port

bash
gio dev --port 4000            # one terminal
GIO_PORT=4000 gio cache explain /   # another

--port applies only to the server it starts; tell gio cache explain the same port through the environment, or use --base.

Good to know

  • The request carries no cookies, so it sees what an anonymous visitor (and a CDN) sees.
  • Exit codes: 0 whenever the server answered, whatever the status; 1 when it could not be reached (is the server running?); 2 for a usage error, including a target or --base that is not a path or an http(s) URL (no request is sent).
  • Each request counts: running it twice on a miss stores the entry, and a request past the TTL starts the background refresh.

Version history

VersionChanges
v0.1.0-beta.8Paths go to the address the server listens on (GIO_PORT / PORT, .env files, gio.toml) instead of port 3000; --base <url>; explains ppr responses and names [cache] enabled = false and the server's own refusals as reasons for bypass. Self-hosted fonts answer static. A target or --base that is not a path or an http(s) URL is a usage error (exit 2), not an unreachable server.
v0.1.0-beta.6Introduced.