Eventual Consistency
Replicas may disagree for a while but converge when updates stop. Design the business around the window.
To an executive
Allowing systems to disagree briefly keeps services fast and available. The business question is how long users can see out-of-date information and what that costs.
To an engineer
Define how long the inconsistency window can last and what users see during it. Use read-your-writes or monotonic reads where needed, and design business processes to tolerate the gap.
The idea
Werner Vogels described eventual consistency as a form of weak consistency: after an update, reads are not guaranteed to return the new value straight away, but if no new updates are made, all reads will eventually return the last updated value. The period in between is the inconsistency window.
Eventual consistency trades immediate agreement for availability and lower latency. The key questions are how long the window is, and what users and processes see during it.
Vogels also described stronger variants that make it easier to live with: read-your-writes (you always see your own updates), session consistency, monotonic reads (you never see older data after newer) and causal consistency. He singled out monotonic reads and read-your-writes as especially useful in practice.
Many businesses already work this way. Banks clear payments in batches, and warehouses reconcile stock counts. The technical choice should mirror the business's tolerance.
Why it works
It keeps systems available. Replicas can accept reads and writes without waiting for each other, so a slow or partitioned replica does not stop the system.
It reduces latency. Requests can be served by a nearby replica without cross-region coordination.
Most business processes tolerate delay. Few users need to see every change instantly; they need to see their own changes and a sensible status.
Where it applies
- Event-driven architectures, where read models and downstream services update after the event is published.
- Multi-region replication, where cross-region coordination would be slow.
- Caches and search indexes, which always lag the system of record a little.
- Integration between bounded contexts, where each context updates its own copy of shared facts.
How to apply
- Make the window explicit. Measure typical and worst-case replication delay, and agree with the business what is acceptable.
- Show pending states. Use statuses such as "processing" in the interface instead of showing stale data as final.
- Give users their own writes. Provide read-your-writes for the person who made a change, even if others see it later.
- Reconcile and compensate. Detect divergence with regular reconciliation, and design compensating actions, such as sagas, for when things go wrong.
Example scenario
After moving to event-driven order processing, customers placed an order and then saw it missing from their order history for a few seconds. Many assumed it had failed, placed it again or called support. The architecture was working as designed; the interface simply showed the read model as if it were final.
The team added a "processing" state shown straight after checkout, and read-your-writes for the customer who placed the order, served from the write side until the read model caught up. Duplicate orders and support calls fell away without changing the underlying architecture.
Questions to ask
- How long can this data be inconsistent, and who would notice?
- What does the user see during that window, and is it acceptable to them?
- How do we detect divergence and reconcile it when it happens?
When not to use it
- Invariants that must hold at every moment, such as preventing overdrafts or double-booking a seat, where you need strong consistency or a single owner of the decision.
- When the window is unmeasured; "eventually" with no bound is not a design.
How it misleads you
Using eventual consistency where invariants must hold at all times, such as preventing overdrafts, and hoping reconciliation will catch the rest. The opposite mistake is demanding strong consistency everywhere out of caution, paying latency and availability costs for data nobody needed to see instantly.
In the wild
- Amazon Dynamo, 2007Amazon designed Dynamo, which backed its shopping cart, to stay 'always writeable' during failures by propagating updates to replicas asynchronously; reads may return stale or divergent versions, which clients reconcile, so a deleted cart item can reappear.ACM Symposium on Operating Systems Principles (SOSP 2007) · 2007 (opens in a new tab)
- Amazon S3 moves to strong consistency, December 2020S3 had been eventually consistent, so a freshly written object might not appear in reads or listings, and data-lake users relied on extra layers such as EMRFS Consistent View or S3Guard; AWS then made reads strongly consistent, removing the need for them.Amazon Web Services · 2020 (opens in a new tab)
Further reading
Last reviewed · Suggest an improvement