Distributed systems comparison

Eventual vs Strong Consistency

One of the core trade-offs in distributed systems design. Strong consistency feels natural and safe; eventual consistency unlocks global scale and high availability. Understanding the difference is essential for any backend engineer.

TL;DR

  • Strong consistency — every read returns the latest write. All nodes agree immediately. Simpler to reason about but sacrifices availability and latency under network partitions. Think Postgres, etcd, Zookeeper.
  • Eventual consistency — replicas converge to the same value over time. Reads may return stale data briefly. Enables higher availability, lower latency, and geographic distribution. Think DynamoDB, Cassandra, DNS.
  • The CAP theorem forces a choice: in the presence of a network partition you can have consistency or availability — not both simultaneously.

Side-by-side comparison

AspectStrong ConsistencyEventual Consistency
GuaranteeEvery read returns the latest writeReplicas converge — reads may be stale briefly
AvailabilityMay reject requests during partition (CP)Always responds, may return stale data (AP)
PerformanceHigher latency (coordination overhead)Lower latency (local reads)
CAP positionCP — Consistency + Partition toleranceAP — Availability + Partition tolerance
Data modelACID transactionsBASE (Basically Available, Soft state, Eventually consistent)
Geo-distributionHard — cross-region consensus is slowEasy — replicas accept writes locally
Use caseFinance, inventory, seat bookingSocial feeds, DNS, shopping carts, caches
ExamplesPostgres, MySQL, CockroachDB, etcdDynamoDB (default), Cassandra, Couchbase, DNS

Code side-by-side

Reading data with different consistency levels:

Strong consistency (Postgres transaction)

BEGIN;
-- Locks the row; no other transaction
-- can read a stale value while we write
SELECT balance FROM accounts
  WHERE id = 42 FOR UPDATE;

UPDATE accounts
  SET balance = balance - 100
  WHERE id = 42;
COMMIT;
-- Reader now sees 100 less, guaranteed.

Eventual consistency (DynamoDB)

// Default: eventually consistent read
// (may return data up to 1 second old)
const result = await dynamo.getItem({
  TableName: 'Accounts',
  Key: { id: { N: '42' } },
}).promise();

// Strongly consistent read (2x cost):
const result = await dynamo.getItem({
  TableName: 'Accounts',
  Key: { id: { N: '42' } },
  ConsistentRead: true,  // <-- opt in
}).promise();

When to choose Strong Consistency

  • Financial transactions. Deducting from a balance, processing a payment, or transferring funds require that every participant sees the same current state.
  • Inventory and seat reservations. Overselling happens when two concurrent reads see the same available quantity and both commit a purchase.
  • Authentication and authorisation. After a user's permissions are revoked, the system must enforce that immediately — not eventually.
  • Leader election and distributed locks. Only one node should believe it is the leader at any given time; etcd and Zookeeper provide this guarantee.

When to choose Eventual Consistency

  • Social media feeds and timelines. Seeing a post appear a second late is invisible to users and saves enormous coordination cost at scale.
  • DNS and configuration propagation. DNS records propagate across the internet over minutes; this is deliberate and well-understood.
  • Shopping carts and wishlists. Losing an item from a cart due to a brief network partition is recoverable; blocking purchases during a partition is not.
  • Geographically distributed systems. A system that spans continents must accept local writes immediately and sync later — the speed of light makes synchronous cross-region consensus impractical.

English phrases engineers use

Strong consistency conversations

  • "We need ACID guarantees for the payment flow."
  • "This query runs in a serialisable transaction."
  • "The system is CP — it will reject writes during a partition."
  • "We use compare-and-swap to avoid lost updates."
  • "Postgres gives us linearisable reads within a transaction."

Eventual consistency conversations

  • "There's a replication lag of a few hundred milliseconds."
  • "The system is AP — it stays up but may serve stale data."
  • "We use read-your-own-writes to make the UI feel consistent."
  • "The replicas will converge once the partition heals."
  • "We apply last-write-wins conflict resolution with vector clocks."

Quick decision tree

  • Financial data, inventory, reservations → Strong Consistency
  • Social feeds, product catalogues, recommendations → Eventual Consistency
  • Must stay available during network partition → Eventual Consistency
  • Multi-region writes with low latency → Eventual Consistency
  • Access control, session invalidation → Strong Consistency
  • Read-heavy, cache-friendly data → Eventual Consistency
  • Distributed lock or leader election → Strong Consistency

Common Mistakes and Trade-offs

A pervasive mistake developers make when evaluating eventual consistency is prematurely optimizing for it. Teams often assume that simply 'embracing' eventual consistency will magically solve performance problems, leading to a cascade of poorly designed systems where queries are repeatedly retried or complex compensating transactions are built to handle minor data discrepancies. The core issue isn't the model itself but a lack of understanding about how to manage the inherent latency and potential conflicts. Focusing solely on 'eventual' without considering strategies like idempotent operations, optimistic locking, or bounded contexts often exacerbates problems rather than resolving them. It's almost always better to start with strong consistency and then explore eventual solutions if performance bottlenecks genuinely emerge—not as a default assumption.

At scale, the trade-off between strong and eventual consistency dramatically shifts. Initially, the latency differences might seem negligible. However, as the number of concurrent operations grows exponentially – think millions or billions – the cumulative effect of 'stale reads' in an eventually consistent system becomes significant. This isn't just about occasional inconsistencies; it's about a steadily degrading user experience. Furthermore, the increased complexity of managing distributed transactions and reconciliation processes to maintain strong consistency at that scale creates enormous operational overhead – often exceeding the initial perceived gains from reduced latency. The cost of maintaining strict serializability can quickly become prohibitive.

The misconception that 'strong consistency is always better' stems from a misunderstanding of its limitations. While it guarantees data accuracy, it fundamentally restricts system scalability and responsiveness. Strong consistency typically relies on techniques like two-phase commit (2PC), which introduces significant performance bottlenecks and reduces the availability of participating nodes. The latency introduced by these mechanisms can severely impact user experience, especially in geographically distributed systems. Eventual consistency, conversely, allows for greater throughput and fault tolerance by accepting temporary inconsistencies, but requires careful design to mitigate potential negative impacts on application logic.

Migrating between strong and eventual consistency isn't a simple flip of a switch; it's a complex architectural undertaking with significant implications. A naive approach – simply changing the data model – will almost certainly lead to disaster. The key is identifying bounded contexts where eventual consistency can be safely applied, while retaining strong consistency for critical operations like financial transactions or user authentication. Furthermore, hybrid approaches—using strong consistency for core services and eventual consistency for peripheral read-only data—are increasingly common. Successfully navigating this requires deep understanding of the application's requirements, thorough testing, and a robust monitoring strategy to detect and address any emerging inconsistencies.

Frequently asked questions

What is strong consistency in plain English?

Strong consistency means that after a write completes, every subsequent read — from any node in the system — returns that new value. There is a single, globally agreed-upon order of operations. It is the behaviour you expect from a single-machine relational database.

What is eventual consistency?

Eventual consistency means that if you stop writing to a key, all replicas will converge to the same value — eventually. Immediately after a write, some replicas may still return stale data. Amazon DynamoDB (by default), Apache Cassandra, and DNS are classic examples.

What does the CAP theorem say about these?

CAP theorem states that a distributed system can guarantee at most two of: Consistency, Availability, and Partition tolerance. Since network partitions are unavoidable, you choose CP (strong consistency, may reject requests during partition) or AP (eventual consistency, always responds, may be stale). Strong consistency = CP; eventual consistency = AP.