Caching deep dive
Route entries reference a caching key. The Router merges the matching policy from src/settings/caching/ into the response so CloudFront (and browsers) can cache consistently.
Mental model
- Application-defined policies — not ad-hoc
Cache-Controlstrings in every handler. - Policies typically include
max-age,stale-while-revalidate, andstale-if-error(exact fields live in the JSON files — treat this page as conceptual). - Route chooses which bucket; policy file chooses TTL strategy.
Common policy names
| Policy (typical) | TTL / behavior (conceptual) | Good for |
|---|---|---|
standard |
Short default (e.g. minutes) | Most JSON / JSON:API content |
mobile |
Similar to standard, separate bucket | Mobile-specific tuning without touching standard |
liveblog |
Fresher updates | Liveblogs and fast-moving editorial |
disabled |
Minimal caching / noindex-style |
Debug-like or highly sensitive responses |
Exact numbers belong in src/settings/caching/*.json — do not duplicate magic numbers in handlers.
Choosing a policy
- Editorial homepage / section — usually
standardormobiledepending on route. - Live tickers / blogs — prefer
liveblogwhen stale content is unacceptable. - Partner RSS — often
standardor dedicated partner policies if split out. - One-off experimental —
disabledonly when you explicitly need to avoid CDN stickiness (discuss with team — impacts cost and origin load).
Stale-while-revalidate
- Lets CDNs serve slightly stale content while fetching fresh copy in the background — improves perceived latency.
stale-if-errorshields users from origin blips.
Operational checks
- Compare CDN age headers vs policy when debugging “old data” — use
?debugga=and identity env to ensure you hit the expected stage/prod origin. - Changing caching affects all routes using that policy — review blast radius.