100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Architecture

Cache Invalidation Strategies

Explores how systems keep cached data consistent with the source of truth, covering TTLs, write-through/write-behind patterns, and explicit invalidation on updates.

CachingIntermediate9 min readJul 9, 2026
Analogies

Cache Invalidation Strategies

Caching speeds up reads, but every cached value is a copy of data that lives somewhere else, and copies drift out of sync the moment the source changes. Invalidation is the discipline of deciding when a cached entry stops being trustworthy and what to do about it. Get it wrong and users see stale prices, outdated inventory counts, or old profile pictures; get it too aggressive and you erase the performance benefit of caching in the first place. There is no universally correct answer — the right strategy depends on how tolerant the application is of staleness, how often the underlying data changes, and how expensive a cache miss is.

🏏

Cricket analogy: A scoreboard operator who doesn't update the run count the instant a boundary is hit leaves fans watching a stale total; update too eagerly on every ball including no-ball reviews and you risk flashing wrong numbers before confirmation.

Time-to-Live (TTL) expiration

The simplest strategy attaches an expiration timestamp to every cached entry. Once the TTL elapses, the entry is treated as absent and the next read repopulates it from the source of truth. TTLs require no coordination between the writer and the cache, which makes them trivially easy to implement and reason about, but they trade correctness for simplicity: for up to the length of the TTL, readers may see data that no longer matches the database. Systems commonly use short TTLs (seconds) for volatile data like stock prices and long TTLs (hours or days) for near-static data like a country list.

🏏

Cricket analogy: A ground's electronic scoreboard that refreshes every 30 seconds regardless of what's happening needs no live coordination with the scorer's desk, but for half a minute after a wicket falls it can still show the wrong batter at the crease.

Write-through and write-behind caching

Write-through caching updates the cache synchronously as part of every write to the database, so the cache is never allowed to go stale in the first place — every write pays the extra latency of touching both stores. Write-behind (write-back) caching instead accepts the write into the cache immediately and asynchronously flushes it to the durable store later, which is fast but risks losing the update if the cache node crashes before the flush completes. Both patterns differ from TTL-based caching in that they proactively keep the cache correct rather than passively letting it expire.

🏏

Cricket analogy: Write-through is like a scorer who updates both the paper scorebook and the electronic board the instant a run is scored, guaranteeing they always match but slowing every single delivery slightly. Write-behind is like updating the paper scorebook instantly but only transcribing it to the official league database at the end of the over, faster ball-to-ball but risking a lost run if the scorer's notes are misplaced before transcription.

Explicit invalidation on write

A more precise approach deletes or updates the specific cache key the moment its underlying row changes, typically triggered from the application code or a database change-data-capture (CDC) stream. This minimizes the staleness window to essentially the propagation delay of the invalidation message, but it requires the write path to know every cache key that could be derived from the data it just changed — a non-trivial bookkeeping problem when the same row feeds multiple cached views (e.g. a user's profile cached both standalone and embedded inside a feed post).

🏏

Cricket analogy: Instead of waiting for the scoreboard's periodic refresh, the scorer directly overwrites just the 'current batter' field the instant a wicket falls — fast, but if that batter's average is also shown on three other panels around the ground, all three must be told, or one screen goes stale.

text
Write path with explicit invalidation:

  Client -> App Server: UPDATE product(id=42).price
  App Server -> Database: UPDATE products SET price=... WHERE id=42
  App Server -> Cache: DEL product:42
  App Server -> Cache: DEL product_list:category:shoes   (derived view)

Next read:
  Client -> App Server: GET product 42
  App Server -> Cache: GET product:42       -> MISS
  App Server -> Database: SELECT * FROM products WHERE id=42
  App Server -> Cache: SET product:42 (value, TTL=300s)
  App Server -> Client: fresh value

A classic bug is invalidating the primary cache key but forgetting derived or aggregate keys built from the same data (category listings, search indexes, denormalized counters). This is often called the 'cache invalidation is hard' trap, and it is one of the two famously hard problems in computer science alongside naming things and off-by-one errors.

Facebook's TAO caching layer combines write-through semantics for the primary object cache with asynchronous propagation to other data centers, accepting brief cross-region staleness in exchange for very low read latency in the region where the write occurred.

Choosing a strategy

In practice, teams blend approaches: TTLs act as a safety net that bounds worst-case staleness even if an explicit invalidation is missed, while explicit invalidation keeps the common case fast and fresh. The right mix depends on read/write ratio — read-heavy, write-rare data favors long TTLs with explicit invalidation on the rare write, while write-heavy data may not benefit from caching at all.

🏏

Cricket analogy: A club blends approaches: the scoreboard auto-refreshes every 30 seconds as a safety net even if the scorer forgets a manual update, while for high-stakes moments like a wicket, the scorer still pushes an immediate manual correction rather than waiting for the timer.

  • TTL-based expiration is simple and requires no write-path coordination but allows bounded staleness.
  • Write-through keeps the cache always correct at the cost of extra write latency on every request.
  • Write-behind is fast but risks data loss if the cache fails before flushing to durable storage.
  • Explicit invalidation on write minimizes staleness but must account for every derived/aggregate cache key.
  • Combining a TTL safety net with explicit invalidation is a common, pragmatic middle ground.
  • The right strategy depends on the read/write ratio and how tolerant the application is of stale reads.

Practice what you learned

Was this page helpful?

Topics covered

#Architecture#SystemDesignStudyNotes#SoftwareEngineering#CacheInvalidationStrategies#Cache#Invalidation#Strategies#Time#StudyNotes#SkillVeris