Strong vs. Eventual Consistency: What Your System Is Allowed to Get Wrong
A payment ledger and a social feed face the same replication question. What each one should buy, what it pays, and where the seam goes.
The scenario
Here’s an illustrative example. A borrower opens your lending app at 11:58 p.m. to make a $400 loan payment before the due date. The payment API writes to the primary database and returns success. The app then redirects to the account page, which reads from a replica in another Availability Zone. That replica is 800 ms behind.
The page still shows $400 due.
The borrower taps “Pay” again. Maybe your idempotency key saves you. Maybe it doesn’t, because the second tap came from a fresh screen with a new key. Either way, you now have a support ticket, a possible refund, and a borrower who trusts your numbers a little less.
Meanwhile, the “Recent activity” widget on the same page also reads from that replica. Nobody would ever notice if it lagged by a few seconds.
Same database, same page, two features with completely different tolerance for stale data. That’s the decision this article is about. It isn’t “which database should we use?” It’s “for this read, what is the system allowed to get wrong, and for how long?”
Strong consistency buys one current truth, and pays for it in latency and availability. Eventual consistency buys speed and uptime, and pays for it in application complexity.
The options, fairly!
Strong consistency
Strong consistency (in its strictest form, linearizability) means the system behaves as if there is a single copy of the data. Once a write is acknowledged, every later read, from any client and any node, sees it or something newer.
Systems get there by making the write wait. A leader takes the write, replicates it to a majority of followers (Raft, Paxos, or a synchronous replica), and only then tells the client “done”. Reads either go to the leader or confirm with a quorum.
Its best case: your application code gets to be naive. You check a balance, then act on it, and the balance you checked is real. No reconciliation jobs, no “pending” states the user has to interpret, no apology emails. For anything that moves money or hands out a scarce resource, that simplicity is worth a lot. If replication is synchronous across sites, losing a whole site loses no acknowledged data (an RPO of zero).
Eventual consistency
Eventual consistency promises less: if writes stop, all replicas will eventually converge on the same value. It says nothing about how long “eventually” is, or what a reader sees in the meantime.
Systems get there by acknowledging first and replicating later. The nearest replica accepts the write, replies straight away, and ships the change to its peers asynchronously.
Its best case: it’s fast and it stays up. Writes don’t wait on a cross-region round trip. Any replica, cache, or CDN edge can answer a read. During a network partition, both sides keep serving. For a feed, a catalog, a like counter, or search, those properties matter far more than freshness, and they’re cheaper. DynamoDB, for example, charges half a read unit for an eventually consistent read of up to 4 KB, against one full unit for a strongly consistent one.
The middle ground most people forget
“Strong vs. eventual” is really a spectrum. Between the poles sit session guarantees, which are often what a product actually needs:
- Read-your-writes: you always see your own updates, even if other people’s lag.
- Monotonic reads: you never see time go backwards between two page loads.
- Bounded staleness: reads may lag, but never by more than N seconds.
The borrower in the opening scenario didn’t need global linearizability. They needed read-your-writes on one page, which you can get by pinning that user’s next read to the primary for a few seconds after a write.
The trade-off table
Two rows deserve a comment.
“Simplicity for app code” is the row teams underestimate. Eventual consistency doesn’t remove complexity. It moves it out of the database and into your services, your UI, and your on-call runbooks.
The latency row is not just about CAP. CAP only describes what happens during a partition. Daniel Abadi’s PACELC formulation (IEEE Computer, 2012) adds the part that hurts every day: else, when the network is healthy, you are still trading latency for consistency on every single write. Partitions are rare. Write latency is on every request.
The spectrum
Even the big platforms move along this line. Amazon S3 was eventually consistent for overwrites for years, then switched to strong read-after-write consistency for all requests in December 2020. DynamoDB global tables, long a multi-Region eventual system, added a multi-Region strong consistency mode in June 2025. You pick the mode when you create the global table, and the default is still eventual. The poles haven’t moved, but the price of standing near the strong end keeps falling.
Scenarios walked through
1. A payment ledger (fintech)
Choice: strong, without hesitation.
A ledger exists to answer “what is the balance right now?”, and its answers gate actions: approve a disbursement, accept a payment, release a hold. If two requests can both read “$500 available” and both spend it, you’ve printed money.
What this looks like in practice? A single-leader relational database (Postgres, Aurora) with transactions, row-level locks or SELECT … FOR UPDATE on the account, and a unique constraint on the idempotency key. Reads that gate actions go to the primary, never to a replica.
What it costs? the ledger write path sits in one region. Users far away pay the round trip. If that region is unavailable, you fail over, and the payment path is down for the duration rather than quietly accepting writes it might later need to reverse. For money, that is the right failure mode.
2. A social feed (consumer media)
Choice: eventual, and it isn’t close.
If a post shows up in a follower’s feed two seconds late, nobody notices. If a like count reads 1,203 instead of 1,204, nobody cares. What users do notice is a slow feed or an error page.
So the feed is built from replicas, caches, and precomputed timelines, all of which lag the source of truth. Like counts are often sharded counters merged in the background. The one place you add a guarantee is read-your-writes for the author: when I post, I must see my post immediately, or I’ll post it again.
3. A multi-region SaaS product (B2B)
Choice: both, split by data type.
Get Syed Noman Ahmed’s stories in your inbox
Join Medium for free to get updates from this writer.
Picture an expense-management product used by companies across the US and Europe.
- Workspace settings, permissions, billing state: strong. A revoked admin must lose access now, not “eventually”. These writes are rare, so paying cross-region latency on them is cheap.
- Expense line items, comments, audit trails being viewed: eventual, served from the user’s nearest region. A few hundred milliseconds of lag on a comment thread is invisible.
- Reports and dashboards: eventual by design. They’re built from a stream or a warehouse that’s minutes behind, and the UI says so.
This is the pattern most mature systems land on: a strongly consistent core surrounded by eventually consistent read models.
What you’re actually paying
The table shows first-order costs. These are the ones that show up on the bill or the on-call rota later.
Strong consistency’s hidden costs
- Geography becomes latency. Quorum writes across regions pay at least one inter-region round trip per write. That’s fine for a settings change. It’s painful for a hot write path.
- Failover is an outage, not a degradation. When the leader’s region goes, writes stop until something is promoted. Aurora Global Database, for example, advertises promotion of a secondary in under a minute, but “under a minute” is still a minute of refused payments that you need a runbook, alerting and a customer message for.
- Hot keys hurt. A single popular account or counter serialized through one leader becomes your throughput ceiling.
Eventual consistency’s hidden costs
- Every consumer must handle anomalies. Stale reads, out-of-order events, duplicates, and conflicting writes. Each service team re-learns this, usually in production.
- Lag is unbounded unless you bound it. “Typically under a second” is a statement about normal days. Aurora’s own docs describe cross-Region replication as typically under one second. Your design has to survive the atypical days, so you need a lag metric, an SLO, and an alarm.
- Data loss on regional failure. With asynchronous replication, whatever hadn’t shipped when the region died is gone or stranded. Your RPO equals your replication lag at the worst moment.
- Reconciliation becomes a product. Someone writes the job that finds and fixes divergence. Someone owns it. Someone gets paged by it.
- The UI has to tell the truth. “Updated a few seconds ago” and “Payment processing” states are design and copywriting work, not just engineering.
Common mistakes
- Reading a decision from a replica. The read-after-write bug in the opening scenario is the classic one. Display reads can be stale; reads that gate an action cannot.
- Choosing per database instead of per operation. Many stores let you pick consistency per request (DynamoDB’s
ConsistentRead, Cassandra's consistency levels, routing a query to the primary). Use that granularity. - Treating “eventually” as “soon”. Without a lag metric and an alarm, you don’t know your consistency model; you’re hoping for it.
- Assuming strong consistency removes the need for idempotency. It doesn’t. Clients retry on timeouts, and a strongly consistent database will faithfully record both attempts.
- Paying for global strong consistency nobody needed. Cross-region quorum on data that only one region ever writes is latency with no buyer.
The interview and design-review angle
A weak answer picks a side:
- “We need strong consistency because it’s a bank.”
A strong answer goes feature by feature.
- “The ledger and the balance check that gates a payment need linearizable reads from the primary. The transaction history list can come from a replica with read-your-writes for the user who just paid. Analytics can be minutes behind. Here’s how we detect and alarm on lag.”
If you’re the reviewer, these questions separate the two quickly:
- “Which reads in this design gate a decision, and where are they served from?”
- “What’s the maximum replication lag you’ll tolerate, and what happens when you exceed it?”
- “If the primary region disappears right now, what data is lost and what stops working?”
Close
Consistency isn’t a property of your database; it’s a promise each feature makes to its users. Make the strong promises where a stale read leads to a wrong decision, make the cheap promises everywhere else, and spend your engineering effort on the seam between them, because that’s where the bugs live.
Where has a stale read hurt you: a double payment, an oversold seat, or something stranger? Tell me in the comments.
Sources
- DynamoDB read and write operations, AWS docs (read-unit cost by consistency mode)
- Consistency Tradeoffs in Modern Distributed Database System Design: CAP is Only Part of the Story, Daniel J. Abadi, IEEE Computer, 2012
- Amazon S3 now delivers strong read-after-write consistency, AWS, December 2020
- DynamoDB global tables with multi-Region strong consistency is now generally available, AWS, June 2025
- How DynamoDB global tables work, AWS docs (consistency modes)
- Amazon Aurora Global Database and Aurora global databases, AWS Prescriptive Guidance









