Cache invalidation
Invalidate cached data after changes and preserve the boundaries between browser, server, Contentful, and edge caches.
Invalidate after changes
Mutations do not invalidate automatically:
await updateProductClient
.execute(updateProductApiContract, { body: input, params: { productId } })
.unwrap();
await dataCache.invalidate(getProductApiContract);
Contract invalidation covers every URL, origin, and private partition for that method/path in the namespace. Use tags for narrower application groups:
const summer = dataCache.public({ ttl: "5m", tags: ["catalog:summer"] });
await dataCache.invalidate("catalog:summer");
Awaiting invalidation confirms storage invalidation, not observer refresh completion. Active local useApi observers refresh in the background and retain old data while fetching. Observers exist only in the same createDataCache coordinator; there is no cross-tab or cross-replica notification.
Invalidation is eventual, and in-flight work may repopulate shared storage. Within one createDataCache coordinator, a local generation prevents new callers from joining pre-invalidation work and prevents that work from publishing to local observers. There is no such promise across coordinators or replicas. The stale fallback recheck is likewise best-effort and eventual.
Boundaries to preserve
- Browser, server, Contentful delivery, and edge caches are separate scopes.
- A Contentful webhook invalidates registered server delivery clients only.
- Invalidation is not CDN propagation, authorization, or a browser purge.
- There is no polling, focus/reconnect refetch, cross-tab broadcast, distributed load lease, or detached stale-while-revalidate.
- Identities are hashed, but bodies are not encrypted by Brix. Use store encryption and access controls.
See API routes, Contentful, and server setup for each integration.