Skip to main content

Command Palette

Search for a command to run...

Consistency Models

What Systems Actually Promise

Updated
7 min read
Consistency Models

Background

One of the most confusing experiences when working with real systems is this:
you do something, the system tells you it worked, and then immediately behaves as if it didn’t.

You update a profile photo and still see the old one.
You change a setting and refresh the page — nothing.

You refresh the screen two or three times. Nothing changes. You check again after half an hour, and suddenly it’s there.

The system is doing exactly what it was designed to do. We may call it a bug but the problem is that most of us don’t have a clear mental model of what the system is actually promising.

That’s where consistency comes in.

One might think of consistency as a binary property — either a system is consistent or it’s not. But once you start looking into distributed systems, that mental model starts breaking down quickly. Consistency isn’t a yes-or-no feature — it’s a set of tradeoffs about agreement, time, and visibility.

This article is my attempt to understand those tradeoffs without hiding behind buzzwords.

What does “Consistency” even mean?

At a very basic level, consistency is about agreement.

If multiple parts of a system are observing the same data, consistency describes if those observations agree, and how fast they agree. That’s it. It’s not about whether the data is “correct” in some moral sense. It’s about whether different observers see the same thing at the same time.

This distinction matters more than it sounds.

A system can accept a write successfully — meaning the system has decided that the change is valid — and still not show that change everywhere immediately. That gap between acceptance and visibility is where most confusion comes from.

Whenever something is written to state, there are two questions one can ask:

  1. Did the system accept the write?

  2. How fast can the other component see that write?

Consistency is often more about the second question.

Why consistency feels simple on one machine

If you’re used to single-process programs, your intuition is solid. You write to a variable, you read it back, and you get the new value. There’s no distance, no delay, no disagreement.

Distributed systems break this intuition because time becomes a problem.

Messages take time. Machines fail independently. A write that succeeds on one machine has to travel before other machines know about it. While that information is in transit, different parts of the system are living in different versions of reality.

This isn’t a rare edge case — it’s the default state of distributed systems.

Replication: visibility, not truth

The databases we use are also systems themselves which have lots of nodes within them. So naturally, for backups or for better availability, we would like replicas.

But replication of data from one node to another takes time.

While replicas are catching up, they can return older data. So, you’ve now encountered inconsistency until the data is copied here — eventual consistency.

A subtle but important thing to know is this: replication “mostly” affects what you can see, not what is true.

A write is accepted by the system somewhere. Replication determines how quickly that decision becomes visible elsewhere. Confusing those two leads to a lot of incorrect reasoning about correctness.

Consistency Models

Strong consistency: Comforting but expensive promise

Strong consistency is the model most people assume by default, even if they don’t use the term.

Behaviorally, strong consistency (often meaning linearizability) means this:

Once a write succeeds, every subsequent read sees that write — meaning the system waits until global agreement before confirming success.

The cost of this promise is coordination overhead and latency.

To ensure that everyone agrees immediately, systems have to wait and synchronize. Latency goes up. Availability can go down. But you accept those if what matters is correctness for your use case.

This is the experience we expect from things which can cause panics — like bank balances, inventory counts, or account permissions. If money moved or access changed, seeing stale data is unacceptable.

Eventual consistency: Acceptable discomfort

Under eventual consistency, the system guarantees that all observers will eventually converge to the same state — but not necessarily immediately.

The write can be accepted immediately — but its visibility can be delayed.

This temporary disagreement is allowed in this model.

Eventual consistency sounds scary until you realize how often you already rely on it.

Social feeds, likes, view counts, recommendations, and profile updates often use this model.

Seeing an outdated like count for a few seconds doesn’t break trust. Waiting long for the system to respond would result in bad user experience.

What’s important here is intent. Eventual consistency isn’t a failure to be strongly consistent; it’s a decision to optimize for responsiveness and availability over immediate agreement.

Other Models

There are still many other models such as causal consistency, read-your-writes, monotonic reads, monotonic writes etc. These don’t replace strong or eventual consistency — they refine what a client experiences on top of them. As an example, I’ve gone through just one of them — monotonic reads below.

Monotonic Reads Consistency

There’s another kind of inconsistency that feels especially jarring, even in systems that are otherwise acceptable.

You read some data.
Later, you read the same data again — and it looks older.

This can happen when one read request went to one replica but the next one went to another replica which was not yet updated.

Nothing about this violates eventual consistency in theory. The system may still converge correctly in the long run. But experientially, this feels wrong. It feels like time moved backwards.

This is where monotonic reads consistency comes in.

Monotonic reads guarantee a simple property: once you’ve observed a particular version of data, you will never see an older version of that same data again. You may not always see the latest update immediately, but you won’t regress.

What’s interesting is that monotonic reads are not about freshness — they’re about directionality. Humans expect systems to move forward, not backward.

This matters more than it initially sounds.

Imagine reading a comment thread, refreshing the page, and suddenly seeing fewer comments than before. Or checking order status and seeing it move from “shipped” back to “processing.” Even if the system eventually fixes itself, user trust takes a hit immediately.

Consistency is a product decision, not just a technical one

One of the most useful things to remember is this: inconsistency is not a bug unless it violates expectations.

Showing the wrong bank balance erodes trust immediately. So it is a bug.

Showing an old profile picture doesn’t (unless your product requirements say otherwise). So it isn’t.

Systems are designed around these expectations, whether explicitly or not.

Once you see consistency as part of user experience and business logic — not just system internals — design decisions start making more sense.

Where this leaves us

We now understand what systems promise, but not how they enforce those promises.

One more thing you can notice — databases “feel” more consistent than caches by default. The answer to why we feel that way is pretty clear once you try to rationalize the concepts we explored so far.

But this feeling can be misleading. Not all databases are strongly consistent in all scenarios — and can deliberately relax consistency under certain conditions.

I will explore this concept further in upcoming articles.

Performance & State

Part 1 of 8

This series covers the concepts required to understand performance of a system and how state plays a vital role in it.

Up next

Exactly-Once Delivery is Impossible

Exactly-Once Effects are not