Skip to main content
chaptertechnical-review

Cache correctness across browser, server and CDN

Why the cache key is a data boundary​

A cache hit is a decision to reuse someone else's computation. Prove equivalence first: which identities, permissions, locales, query parameters, deployment versions and freshness windows can share this value? Optimizing the hit ratio before defining equivalence can optimize a data leak.

Layer inventory and ownership​

LayerTypical lifetimeInvalidating event
Request memoizationOne request/renderEnd of request
Server data cacheMany requestsMutation, permission revision, TTL, deployment policy
CDNShared across viewersPurge/version change/expiry under provider rules
Browser HTTP cacheBrowser profileValidator or freshness policy
Client query storeApp/sessionMutation, logout, account switch, scope change
Service workerWorker-controlled storageExplicit version and eviction policy

The fixture's scoped key includes tenant, user, role, permission revision and resource. This sacrifices sharing to make the security model obvious. A production application may safely share tenant-public data, but must prove that all users sharing the key can see identical fields. A tenant ID alone is insufficient for role-filtered views.

Implementation and race repair​

The bounded cache combines TTL, capacity and single-flight requests. Invalidation removes the cached entry and detaches any current in-flight promise. A late response publishes only if it is still the registered promise for that key. Otherwise invalidation can be undone by a request that started before the mutation.

A promise shared across callers also shares failure and underlying work. Do not let one caller abort a request that other callers still need unless you implement reference-counted ownership. The demonstration deduplicates requests; it is not a full client query library.

Use no-store for the personalized HTTP response even when the server internally caches an authorized projection. HTTP headers do not describe or invalidate every application cache. Conversely, a client cache library's invalidation cannot purge the CDN.

HTTP decisions and failure modes​

no-cache permits storage but requires validation before reuse; no-store forbids storing the response. max-age describes freshness and s-maxage controls shared-cache freshness. Vary extends response selection using request headers under HTTP semantics; confirm the CDN's actual cache-key policy rather than assuming every provider honors every variation. These semantics come from RFC 9111.

Use content-addressed asset names with long immutable caching and retain previous assets during rollout. A stale HTML shell can reference an old chunk after deployment. Purging HTML does not repair already-open tabs. Offer a safe reload path that preserves drafts when lazy chunk loading fails.

Exercise, answer and rollback​

Temporarily replace the key with resource alone and run the tenant-switch test; it must expose the leak. Restore the scoped key, then invalidate while a slow read is pending and prove the old result is not republished. For a CDN experiment, record request headers, response Age, cache status, region and body hash. Local Node tests cannot establish global purge latency. Roll back a broken caching rule by bypassing shared storage first; preserve logs needed to determine exposure scope.

Executable reference and sources​

Implementation · Behavioral evidence · Primary source.

Run the projects and assessment. Human review is pending.