Cache Configuration
The [cache] section controls PRISM's in-memory cache for rendered HTML. Caching avoids redundant renders and dramatically reduces response times for repeat requests.
TOML Example
[cache]
enabled = true
max_entries = 10000
max_memory_bytes = 268435456
default_ttl_secs = 3600
grace_period_secs = 300
strip_query_params = ["utm_*", "fbclid", "gclid", "msclkid", "_ga"]
error_ttl_secs = 30
skip_authenticated = true
synthesize_cache_control = true
[[cache.rules]]
pattern = "/blog/**"
ttl_secs = 86400
[[cache.rules]]
pattern = "/products/**"
ttl_secs = 7200
[[cache.rules]]
pattern = "/special-page"
ttl_secs = 60
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
enabled | Boolean | true | Enable or disable caching entirely |
max_entries | Integer | 10000 | Maximum number of cached pages |
max_memory_bytes | Integer | 268435456 (256 MiB) | Maximum memory for cached content |
default_ttl_secs | Integer | 3600 (1 hour) | Default time-to-live for cached entries |
grace_period_secs | Integer | 300 (5 minutes) | Serve stale content while revalidating in background |
rules | Array of {pattern, ttl_secs} | [] | Path-specific TTL overrides using glob patterns |
strip_query_params | Array of Strings | ["utm_*", "fbclid", "gclid", "msclkid", "_ga"] | Query parameters to strip from cache keys (supports globs) |
error_ttl_secs | Integer | 30 | TTL for caching error responses (status >= 500). 0 = do not cache errors |
skip_authenticated | Boolean | true | Skip caching for requests with Authorization header or session cookies |
synthesize_cache_control | Boolean | true | Add Cache-Control header to rendered responses if origin did not provide one |
vary | Array of Strings | [] | Request headers that fragment the cache key AND are forwarded to Chrome during render. See vary below. |
Detailed Explanation
max_memory_bytes
The default is 256 MiB (268435456 bytes). When this limit is reached, the least recently used entries are evicted. Size your allocation based on average page size and expected unique URLs.
grace_period_secs
When a cached entry expires, PRISM can still serve the stale version for up to grace_period_secs while triggering a background re-render. This prevents cache stampedes and ensures visitors never wait for a cold render.
rules
TTL rules are evaluated in order; the first matching glob pattern wins. If no rule matches, default_ttl_secs is used.
[[cache.rules]]
pattern = "/blog/**"
ttl_secs = 86400 # Blog posts: 24 hours
[[cache.rules]]
pattern = "/products/**"
ttl_secs = 7200 # Product pages: 2 hours
Place more specific patterns before broader ones, since the first match wins.
strip_query_params
Marketing and analytics query parameters are stripped from cache keys to avoid duplicate cache entries for the same page. Supports glob patterns (e.g., utm_* matches utm_source, utm_medium, utm_campaign, etc.).
skip_authenticated
In render-all mode, requests with an Authorization header or session cookies are not cached, since they may contain personalized content. In bot-only mode this is less relevant since bots rarely send authentication.
synthesize_cache_control
When the origin does not include a Cache-Control header, PRISM adds one based on the configured TTL for that path. This helps downstream CDNs and browser caches respect PRISM's caching strategy.
error_ttl_secs
Error responses (HTTP 500+) are cached for a shorter duration to avoid serving errors for extended periods while still providing some protection against repeated failing renders. Set to 0 to disable error caching entirely.
vary
Use vary when the same path produces different rendered HTML depending on a request header — most commonly Accept-Language for multilingual SSR.
When configured, PRISM does two things for every header in the list:
- Fragments the cache key so that requests differing only in the header value are stored as separate cache entries.
- Forwards the header value to Chrome via
setExtraHTTPHeadersso the SSR can actually produce variant-specific HTML. Without this, vary would just multiply identical cache entries — so PRISM does both atomically.
[cache]
vary = ["accept-language"]
Header names are case-insensitive. Header values are used as raw strings — en-US and en-us are stored as different variants. Pre-normalize at your CDN or reverse proxy to avoid cache fragmentation; for example, collapse the browser default Accept-Language: en-US,en;q=0.9 to a single primary tag like en before forwarding to PRISM.
Default is empty ([]) — no vary, one cache entry per path. Leave it empty for single-language sites.
:::tip Why not vary on every header by default?
Each unique combination of vary values multiplies the cache footprint. Defaulting to vary on, say, Accept-Language would explode cache size for sites that don't actually serve language-varied HTML. Better to opt in.
:::
:::warning Vary headers and bot/CDN behavior
Bots typically don't send Accept-Language, so they all share one variant — fine for SEO. But CDN caches in front of PRISM must also vary on the same header, or they'll serve the wrong language. Configure Vary: Accept-Language on your CDN to match.
:::
Example Use Cases
E-commerce site with mixed content freshness
[cache]
enabled = true
max_entries = 50000
max_memory_bytes = 536870912 # 512 MiB
default_ttl_secs = 1800
[[cache.rules]]
pattern = "/products/**"
ttl_secs = 3600
[[cache.rules]]
pattern = "/categories/**"
ttl_secs = 7200
[[cache.rules]]
pattern = "/blog/**"
ttl_secs = 86400
Development / debugging with caching disabled
[cache]
enabled = false
Aggressive caching for mostly-static site
[cache]
enabled = true
max_entries = 100000
default_ttl_secs = 86400
grace_period_secs = 3600
error_ttl_secs = 60