Course contentsShow
← Databases & SQL
Lesson 1741 of 1,95316. Distributed Data ArchitecturesFree lesson

Cache Invalidation and Coherency

Sync cache state across distributed nodes to avoid serving stale data.

In this lesson, you will learn how to maintain data consistency across distributed cache nodes to ensure your application never serves stale information.

The Challenge of Distributed Caching

When your system scales horizontally, you likely deploy local or distributed caches to reduce read latency. However, when a write occurs in your database, a node-specific cache might still hold the "old" value. If another service node reads from its local cache, it unknowingly serves stale data, breaking consistency. Achieving Coherency means ensuring that all nodes in your system agree on the state of the data, despite having multiple cached copies.

Invalidation Strategies

To keep caches synchronized, you must manage the lifecycle of cached entries. The two primary approaches are:

  1. Write-Through/Write-Around: When updating a record, the application or the database (via an Outbox Pattern or trigger) explicitly deletes or updates the cache entry across all nodes.
  2. Time-to-Live (TTL): A simpler, though eventually consistent, approach where entries expire automatically. This is often insufficient for high-concurrency systems requiring strict read-after-write consistency.

A more robust pattern in distributed systems is to use a Cache Invalidation Bus. When a write operation completes, an event is broadcast to all nodes to invalidate their local keys.

-- Conceptual example of an invalidation signal via an event bus
-- After a successful UPDATE in the primary database:
INSERT INTO outbox (aggregate_id, event_type, payload) 
VALUES ('user:123', 'CACHE_INVALIDATE', '{"key": "user_123_profile"}');

-- Subscriber nodes receive this and execute:
-- Redis: DEL user_123_profile

Dealing with Race Conditions

A critical danger is the "Cache Stampede" or race condition: Node A invalidates the cache, but before it can update it, Node B reads the stale database value and repopulates the cache with the old data. To avoid this, you should pair your invalidation logic with Distributed Locking (Concept 14). By locking the record during the update and the subsequent cache invalidation, you ensure that no read can repopulate the cache until the underlying data is fully updated and the cache is cleared.

Key Takeaway: Cache coherency is a trade-off between latency and consistency; you must use explicit invalidation signals or distributed locks to ensure nodes do not serve stale data after a state change.