Prasoon AI
ServicesInsights
Let’s talk
GOOD IDEAS DESERVE GREAT ENGINEERING.Explore the possibilities.

WHAT I BUILD

AI systems

Agents, private knowledge, and production AI.

SaaS platforms

Scalable software, from first release to growth.

HOW WE WORK

Services

Engineering expertise for your next challenge.

Industries

Solutions grounded in your business context.

IDEAS & PERSPECTIVES

Insights

Practical thinking on AI and architecture.

About my approach

Bridging research and production.

Available for select projectsDiscuss your project
All insights/Performance Engineering

Performance Engineering / Practical engineering

Cache Invalidation: Versioned Reads and Explicit Staleness Budgets

Prevent stale refills, cross-user responses, and cache stampedes by treating freshness, authorization, and concurrency as separate design decisions.

P.
Prasoon ThakurAI systems architect
September 20, 20264 min read
THE ENGINEERING SERIESPerformance Engineering
VERSIONED REPRESENTATIONS
product:204:v12 Late refill · old key
product:204:v13 Current representation
New version. Separate cache identity.
Performance EngineeringIdeas, connected to implementation.
In this article6 sectionsContents +
  1. 01Freshness is a product requirement
  2. 02Keep HTTP storage rules distinct from application caching
  3. 03Model the stale-refill race
  4. 04Define the representation key completely
  5. 05Coordinate refill work without making locks permanent
  6. 06Observe freshness as well as hit rate

Freshness is a product requirement

A stale article title is usually tolerable. A stale account suspension, inventory promise, or permission decision may not be. Applying one cache duration across those values turns a performance setting into an undocumented business policy.

For every cached representation, define an acceptable age, the consequence of stale data, the owner of invalidation, and the behavior when the source is unavailable. This article proposes a practical design based on versioned representations and bounded stale serving. It does not assume that a cache can provide database-level consistency on its own.

Keep HTTP storage rules distinct from application caching

HTTP no-cache requires successful validation before reuse; it does not prohibit storage. no-store prohibits storage under the directive's rules. private restricts shared caches, while Vary participates in selecting the appropriate representation. These distinctions matter when responses pass through browsers and CDNs. RFC 9111

An internal Redis cache does not automatically inherit those semantics. The application still decides what it stores, how it identifies the representation, and when it may serve it. Document the browser, CDN, framework, and application cache layers separately; disabling one does not disable all of them.

Model the stale-refill race

The ordinary cache-aside sequence contains a subtle window:

  1. Reader A misses the cache and reads database version 12.
  2. Writer B commits version 13 and deletes the cache key.
  3. Reader A finishes serialization and stores version 12 under the now-empty key.
  4. Future readers receive version 12 until expiry or another invalidation.

A second delayed deletion reduces the window probabilistically but does not prove correctness. Instead, consider immutable value keys containing the entity version. Readers of version 13 cannot be overwritten by a late fill for version 12.

The remaining challenge is discovering the current version. If that pointer is itself cached, it has its own staleness budget. For operations requiring strict current state, resolve the version from the authoritative database or bypass the cache. Be explicit about this cost rather than claiming versioned keys eliminate every stale read.

Define the representation key completely

System Source
entity: product_204
version: 13
workspace: workspace_7
locale: en-GB
currency: GBP
price_list: contract_4
representation_schema: 3

This illustrative key includes dimensions that can change the returned value. Omit currency and a price can be reused incorrectly. Omit contract pricing and one customer may see another customer's offer. Omit representation schema and a rolling deployment may deserialize an incompatible value.

Avoid putting raw credentials or sensitive personal data into keys. Keys appear in diagnostics and metrics. Hashing the full authorization token is also a poor substitute for an explicit permission model and can create uncontrolled cardinality.

Cache shared data only after determining which portions are genuinely shared. Recheck current authorization before returning a representation, especially after membership changes or revocation. A cached result cannot grant access by itself.

Coordinate refill work without making locks permanent

When a popular key expires, thousands of identical misses can overwhelm the database. A single-flight mechanism lets one request refill while others wait briefly or receive permitted stale data. Bound the wait and the refill lease; a crashed owner must not block the key forever.

Use an ownership token for lock release so an old worker cannot delete a replacement worker's lease. If multiple refill generations can overlap, ensure an older result cannot replace a newer one. Add expiry jitter to spread routine refreshes, but do not confuse randomized expiry with concurrency correctness.

Data classCandidate failure behaviorDisallowed shortcut
Public editorial contentServe bounded stale contentServe unbounded stale content indefinitely
Analytics previewShow age and degraded statusPresent stale data as live
Permission decisionRevalidate or fail closedExtend revoked access for availability
Checkout priceRecompute at commitmentCharge from an old display cache

Observe freshness as well as hit rate

A high hit rate can describe a very fast incorrect system. Record representation age, source version, refill duration, stale-serving count, and invalidation lag. Keep metric labels bounded; entity IDs belong in sampled diagnostic records, not unrestricted time-series dimensions.

Test the stale-refill sequence with controlled barriers. Expire a hot key under load, kill the lease holder, change permissions during a refill, and deploy two representation schemas simultaneously. Verify that fallback traffic cannot overwhelm the database when the cache is unavailable.

Start by caching expensive, read-heavy values with tolerable staleness. Expand only when the freshness contract, invalidation path, and degraded behavior are understood. The performance benefit should be measured alongside the consistency behavior the product actually needs.

Frequently asked questions

Does deleting a cache key after a write prevent stale reads?

Not completely. A reader can fetch old database state before the write and refill the cache after invalidation. Version-aware publication or another coordinated protocol is needed when that race is unacceptable.

Does Cache-Control private mean the response cannot be stored?

No. It restricts shared-cache storage. A private browser cache can still store the response subject to other directives. Use the appropriate freshness and storage controls for the actual data.

About the author

Prasoon Thakur

Prasoon is an AI systems architect focused on reliable agents, retrieval, LLM operations, and scalable SaaS platforms. His work connects model behavior to the controls production teams need: evaluation, observability, security, and cost discipline.

GitHubUpwork profile

Need a reliable production system?

Turn the patterns in this guide into a scoped system design, delivery plan, and measurable reliability target.

Start a strategy session

Related insights

Capacity Engineering

Backpressure by Design: Admission Control for Expensive APIs and Jobs

5 min read
API Engineering

Cursor Pagination Under Concurrent Writes: A Consistency Contract

4 min read

Active Now • 24/7 Availability

Engaging with teams
from Silicon Valley to Singapore.

I operate as a high-availability resource. To maintain secure collaboration, all global engagements are managed via Upwork.

Discuss your project Direct collaboration through Upwork.

Global / Remote

24/7 Timezone Agnostic

Syncing with USA, Europe, UAE & Singapore

Secure Engagement

Top Rated Expert on Upwork

Prasoon AI

Thoughtful architecture.
Software built for the real world.

Based online. Working worldwide.

Explore

AI systemsSaaS platformsServicesIndustries

Discover

Engineering insightsMy approach

Connect

Upwork GitHub Open to project inquiries

© 2026 Prasoon Thakur

Independent thinking. Dependable engineering.Back to top ↑