[Deep Dive #16] Data Cache Lanes - discussion
We tried introducing explicit cache lanes and it made some routes way calmer, but it also made it obvious how many screens were relying on invisible dedupe.
How many lanes do you actually use in practice (bypass/stale-ok/strict/etc.) without it turning into bikeshedding? Do you render cache lane evidence in prod so support can tell which posture was active? And how do you keep lane selection consistent across routes and panels?
Comments (10)
Back to latestDo you keep lanes per route, or do you have an app-wide default?
I'm worried every team will invent their own lane semantics.
We keep a small global enum and then routes choose their default lane explicitly.
The important part is the evidence: you can see the lane in screenshots and tests, so drift isn't silent.
Ok, the "evidence makes drift visible" part is what makes it believable.
We ended up with three lanes max: bypass, stale-ok, strict.
Anything beyond that was mostly naming disagreements, not behavior differences.
This matches the posture in Data Fetching and Caching Best Practices.
A concrete lane evidence pattern that helped us debug "why did it refetch":
tsx
import { useCacheBypass, useGroupState, useRenderFetch } from "react";
export function CacheLaneShell({ children }) {
const group = useGroupState("cache", { policy: "bust", mode: "fresh" });
return <section data-policy={group.read("policy")} data-mode={group.read("mode")}>{children}</section>;
}
export function OrdersPanel() {
const orders = useRenderFetch("/api/lane/items");
const stats = useCacheBypass("/api/lane/stats");
return <div data-count={orders.items.length} data-stats={stats.total} />;
}
Now a screenshot can answer "what lane were we in" without digging into devtools.
Counterpoint: cache lane evidence in prod feel risky because it can become a crutch for not having real monitoring.
We render them in internal builds and in QA, but not for end users.
We do something similar: prod renders a tiny evidence line (lane only), internal renders the full key/status.
The main goal is the screenshot story, not exposing internals.
Lane selection consistency came from making it a route shell default, not a per-hook option.
Hooks can override, but the shell sets the baseline and renders the posture once.
We used lanes as part of release cadence. During migrations we flipped more routes to bypass and rendered that as evidence so people stopped being surprised.
If lane choice can change behavior, it needs an owner and render-visible evidence. Otherwise it's just another invisible knob that breaks stuff.
We also kept lanes out of component props. The moment you pass cacheLane down, it's basically global-ish configuration again.
Shell-owned defaults + evidence kept it sane.
Our metric was: can a support person tell whether "stale data" complaints are real or just stale-ok doing its job? Evidence helped a lot.
Three lanes max is the right take. Anything beyond that becomes taxonomy work, not app work.