Causal Consistency vs Linearizability: Choosing the Right Order
March 2, 2026
Consistency is not one thing. It is a menu of guarantees, and the two you should be able to draw on a whiteboard are linearizability and causal consistency.
Linearizability says there exists a single global order of operations that respects real time. If a write completes before a read starts on a wall clock, the read must see that write. The system behaves as if there is one copy of the data behind the scenes. To deliver this you almost always need consensus: Paxos, Raft, or a single primary that linearizes through itself. You pay in latency and in availability during partitions.
Causal consistency is weaker and cheaper. It says: if operation A happened-before operation B, every observer that sees B must also see A. Operations that are concurrent under the happened-before relation can be observed in any order, even disagreeing orders, across different readers. You can implement causal consistency with vector clocks or with monotonic LSN tags piggybacked on requests. No consensus required.
The classic example. Alice posts "Hello." Bob reads the post and comments "Nice one." Under linearizability, every reader sees a single timeline: post first, comment second, always. Under causal consistency, every reader still sees the post before the comment, because the comment causally depends on the post. But two unrelated posts from two different friends might appear in different orders to different readers, and that is allowed.
The production failure worth remembering. A global chat app ran on a linearizable backend and was eating a 200 ms p99 on send. The team demoted to "session causal" consistency: each user session carried its own causal context, and writes only waited for that context to be respected. Latency dropped 4x. Then customers started reporting that in group chats with two friends, messages from friend A and friend B sometimes appeared in inverted order on different devices. The bug was that causal context was scoped per session, not per conversation, so messages from different senders into the same room had no causal link tying them together.
The fix was to attach the conversation's last observed LSN to every send, so the causal grain matched the user's mental model. Same consistency level, different scope, problem gone.
When you pick a consistency model, name the scope along with it. Per key, per session, per conversation, per tenant. The model only protects what its context covers.
Linearizability buys a single global order at the price of consensus. Causal consistency preserves happened-before without coordination, and is enough for most user-facing flows if you scope the causal context correctly.
Originally posted on LinkedIn. View original.