Tacnode™
Glossary
Data Consistency

What Is Cache Coherence?

Cache coherence is the property that all cached copies of a shared piece of data reflect writes to that data in a single agreed order, so no reader observes a value that contradicts what another reader sees. The term originates in multiprocessor CPU design, where hardware protocols keep per-core caches synchronized; by extension, it names the same problem in distributed systems, where multiple services hold independent caches of the same source data.

Updated

What is cache coherence?

In a multicore processor, each core has private caches (L1, and often L2) holding copies of lines from shared memory. Without coherence, core A could write a new value to address x while core B keeps reading its old cached copy indefinitely — the program would behave as if the write never happened. Coherence protocols prevent this by enforcing two informal requirements: write propagation (a write to a location eventually becomes visible to every cache holding that location) and write serialization (all cores observe writes to the same location in the same order).

Coherence is deliberately narrower than a memory consistency model, and the distinction matters for CS students: coherence governs ordering of accesses to a single memory location, while the consistency model (sequential consistency, x86-TSO, ARM's weaker models) governs how accesses to different locations may be reordered relative to each other. A machine can be fully coherent and still allow reorderings that surprise programmers — that is what memory barriers exist to control.

The second, looser usage applies the same vocabulary to application-level caches: when several services cache the same database rows in Redis or in process memory, "coherence" describes whether those copies agree. The crucial difference is that no hardware protocol exists at this layer — coherence must be engineered, or its absence accepted.

How cache coherence works

Hardware achieves coherence with invalidation-based protocols, of which MESI is the canonical example. Every cache line is in one of four states: Modified (this cache holds the only copy, and it is dirty), Exclusive (only copy, clean), Shared (clean, possibly present in other caches), or Invalid. Before a core may write a line, it must gain exclusive ownership by broadcasting an invalidation — either snooped by all caches on a shared bus or mediated by a directory that tracks which caches hold each line. Other cores' copies transition to Invalid, and their next read fetches the current value. The protocol makes it impossible to read a stale copy after the write completes; the cost is coherence traffic, which is why heavily contended cache lines (and false sharing of unrelated data on one line) degrade multicore performance.

Distributed application caches have no equivalent of the invalidation bus. Each service's cache is refreshed by its own mechanism — a TTL, a pub/sub listener, a change-data-capture consumer at its own stream offset — so copies converge at different rates and the system is, at best, eventually coherent. Engineering approximations exist: a single shared cache tier instead of per-service caches (removing copies rather than coordinating them), leases that grant a bounded-time right to cache an item, version checks on read, and centralized cache invalidation fan-out. Each buys tighter agreement at the price of latency, availability, or coupling — the same trade hardware pays in coherence traffic.

Why cache coherence matters in real-time systems

Hardware coherence is a solved problem; its distributed analogue is not, and the failure mode is subtle. In a typical microservice estate, each service maintains its own cache or state pipeline at a different propagation stage: an inventory service's stock cache is two seconds behind the event stream while the checkout service's copy is 200 milliseconds behind, so one service reserves units a concurrent order already consumed. Neither cache is malfunctioning — but the two services are looking at different versions of reality and can reach contradictory conclusions about the same item at the same moment.

This is the structural point the CPU analogy illuminates: the problem is not the speed of any individual cache, which is usually excellent, but the divergence between copies that no one component can observe or bound. Per-cache fixes — shorter TTLs, faster pipelines — narrow each copy's staleness without ever making the copies agree, because each pipeline still advances independently. How this divergence emerges from the composition of individually reasonable systems is examined in the modern data stack's coherence problem; the freshness dimension of each individual copy is covered in what is data freshness.

FAQ

Related terms

Further reading