[cache]
The page cache: a memory LRU in front of a disk directory for pages that export revalidate, with page ETags and stale-while-revalidate.
[cache]
memory_max_entries = 5000
disk_max_bytes = 1073741824 # 1 GiBWhich pages are cached is decided per page, with the revalidate export; this section sizes the cache and switches its parts. Caching & Revalidating explains the model.
Reference
| Key | Default | Description |
|---|---|---|
enabledboolean | true | Store and serve pages that export revalidate. With false every response answers X-Gio-Cache: bypass and every request costs a render, but pages still send the Cache-Control their revalidate asks for, so a CDN in front can keep caching them. |
memory_max_entriesinteger | 1000 | Pages kept in the in-memory LRU. Pages pushed out of memory are still served from the disk tier. At least 1; enabled = false is the off switch. |
disk_enabledboolean | true | Keep a disk tier behind the memory LRU. It holds what memory drops and outlives restarts. false writes no files: a page the LRU drops renders again, and the cache starts empty after every restart. |
disk_pathstring | ".gio/cache/pages" | The disk tier's directory, relative to the project root and below it (not ., not absolute). It must not be, contain or sit inside app/ or public/. GIO_CACHE_DIR overrides it, may be absolute, and is held to the same placement rule. |
disk_max_bytesinteger | 536870912 | Size cap of the disk tier (512 MiB); past it the oldest entries are deleted. |
etagboolean | true | Send a weak ETag with pages and answer a matching If-None-Match with 304 Not Modified. Turn it off for a CDN that mishandles weak validators, or when the app sets its own. |
swr_multiplierinteger | 10 | A page stays servable stale (while one background render refreshes it) until it is this many times its revalidate old. The same window sizes the stale-while-revalidate directive CDNs read. |
Behavior
X-Gio-Cache on every page response says what happened: miss; stored, hit; ttl=<seconds>, stale; age=<seconds>; revalidating (served stale while one render refreshes it), or bypass (not cacheable, or the cache is off). A page with a cached PPR shell reports ppr; shell=stored, ppr; shell=hit or ppr; shell=stale; age=<seconds>; revalidating. A cached page carries, with revalidate = 60 and the default multiplier:
cache-control: public, max-age=0, s-maxage=60, stale-while-revalidate=540
etag: W/"50b12c1658e2f16a5b78a9b93c564426"s-maxageis what is left of the page'srevalidatewindow;stale-while-revalidateis what is left ofrevalidate × swr_multiplierafter that. Browsers always revalidate (max-age=0).- A render that read cookies, the
Authorizationheader, the client address, host or scheme (ctx.ip,ctx.host,ctx.scheme), or that sets a cookie, is personal: it is sentprivate, no-cacheand never stored. - A page answered to a request with an
Authorizationheader, through a guard, or in a locale negotiated from request headers goes outprivate, no-cachewithout an ETag, even when the page cache served it: one URL serves several audiences there. - A
Cache-Controlthe app or a[[headers]]rule sets always wins. - Entries are keyed by the deployment id: a new build or a change to the settings pages render with drops what an earlier one stored on disk.
Startup logs page cache disabled ([cache] enabled = false): every request renders or page cache is memory only ([cache] disk_enabled = false) when you turn a part off. None of these keys logs a warning.
Errors
invalid `cache.memory_max_entries`: invalid value: integer `0`, expected a nonzero usizeinvalid `cache.disk_path`: expected a directory inside the project, relative to its root (".gio/cache/pages"); use GIO_CACHE_DIR for a path outside it[cache] disk_path: the page cache directory ./public/cache is inside the public/ directory (...) - give the cache a directory of its own, such as .gio/cache/pagesunknown key `cache.memory_mb` - the memory cache is bounded by entry count: use memory_max_entries (default 1000), and[cache.redis], which is refused: there is no Redis backend yet.
Examples
A CDN does the caching
Render every request at the origin and let the CDN keep pages for their revalidate:
[cache]
enabled = falseRead-only filesystem
[cache]
disk_enabled = false # memory only: nothing is written under .gio/cache/pages
memory_max_entries = 2000Without the disk tier (or with enabled = false) the page cache directory is not even created. The server still creates .gio/fonts (GIO_FONTS_DIR) and, with the image optimizer on, .gio/cache/images (GIO_IMAGE_CACHE_DIR): create them before deploying or point those variables at a writable path. A directory that cannot be created stops startup with its path and the setting that placed it.
Never serve stale pages
A page past its revalidate window renders before it is served:
[cache]
swr_multiplier = 0Cache outside the project
GIO_CACHE_DIR=/var/cache/my-app npm startGood to know
- Each server instance has its own cache. Instances that share a disk directory serve the pages each other stored, but each keeps its own memory LRU - purge every instance.
- GioJS only ever deletes its own entry files (
<sha256>.json) in the disk directory, but give it a directory of its own. - In development the cache is cleared each time a source change restarts the worker, and cached pages get no ETag.
export const revalidate = falsecaches a page for a year (31536000 seconds).
Not configurable
- Personalized renders bypass the cache. There is no switch to store a page that read cookies or the client address: it would be served to everyone. Cache the shell with
shell = 'cache'and personalize inside Suspense holes instead. Set-Cookieand hop-by-hop headers are never stored with a page.
Related
- Caching & Revalidating
revalidateandtagsrevalidatePath,revalidateTagand[revalidate]- Caching Layers
Version history
| Version | Changes |
|---|---|
v0.1.0-beta.8 | Introduced as a gio.toml section: memory_max_entries, disk_path and disk_max_bytes are honored, and enabled, disk_enabled, etag and swr_multiplier added. memory_mb and [cache.redis] are rejected with a hint. The disk directory may not overlap app/ or public/. |