DISTRIBUTED SYSTEMS / SYSTEM CONCEPT BRIEF

Eventual consistency

Eventual consistency guarantees that if no new updates are made, all replicas will eventually return the same value.

IntermediatePhase 05 / Topic 11 of 17RequirementsTrade-offsFailure modes
01

Overview

Eventual consistency guarantees that if no new updates are made, all replicas will eventually return the same value. It allows replicas to be temporarily different, which lets systems accept writes during partitions and serve reads from the nearest replica without waiting for coordination.

The cost is anomalies the application must tolerate or hide: stale reads, reading your own write and not seeing it, out-of-order updates, and conflicting concurrent writes. Well-designed eventually consistent systems add session guarantees, idempotent and commutative updates, and conflict resolution strategies.

News spreading through a town

When the mayor announces something, some people hear it immediately and others hear it an hour later from neighbors. For a while, people disagree, but eventually everyone knows the same news.

02

When to use it

  • Feeds, likes, view counts, recommendations.
  • Multi-region systems that must stay fast and available.
  • Asynchronous pipelines between microservices.
  • Caches, search indexes, and read models.
03

Where it shows up in interviews

Asynchronous read models

Recognize it when: search index or cache updated after the DB.

  • Design product search
  • Design a notification feed
Multi-region writes

Recognize it when: users write in different regions.

  • Design a global social network
  • Design a collaborative app
04

Where it is used in real software

DNS

Record changes propagate as caches expire, which can take minutes to hours.

Amazon DynamoDB global tables

Replicate across regions asynchronously with last-writer-wins conflict resolution.

Microservices with events

Order service publishes OrderPlaced; shipping and analytics update their own data seconds later.

05

Key terms

Convergence
Replicas reach the same state once updates stop.
Stale read
Reading an older value from a lagging replica.
Last-write-wins
Resolve conflicts by highest timestamp; simple but can lose updates.
CRDT
Data types that merge concurrent updates deterministically.
Anti-entropy
Background comparison and repair of replicas.
06

How it works, step by step

  1. 1
    Write locally

    Accept the write at the nearest replica.

  2. 2
    Propagate asynchronously

    Replication stream, gossip, or events.

  3. 3
    Detect conflicts

    Versions or vector clocks identify concurrent updates.

  4. 4
    Resolve conflicts

    LWW, merge function, or CRDT.

  5. 5
    Hide anomalies in the product

    Optimistic UI, read-your-writes routing, 'processing' states.

07

Conflict resolution strategies

Two regions update the same record concurrently

Step 1 / 4
StrategyHowRisk
Last-write-winsKeep highest timestampSilently drops one update
Merge functionApplication merges (union of cart items)Deleted items can reappear
CRDTMathematically mergeable types (counters, sets)Limited data types
Ask the userShow both versionsPoor experience at scale

NOWStrategy: Last-write-wins | How: Keep highest timestamp | Risk: Silently drops one update

Choose per data type: counters and sets as CRDTs, profile fields with LWW, and money never eventually consistent without a ledger.

08

Implementation

// Grow-only counter: each node increments its own slot; merge takes the max per nodetype GCounter = Record<string, number>; const increment = (c: GCounter, nodeId: string, by = 1): GCounter => ({ ...c, [nodeId]: (c[nodeId] ?? 0) + by }); const merge = (a: GCounter, b: GCounter): GCounter => {  const out: GCounter = { ...a };  for (const [node, n] of Object.entries(b)) out[node] = Math.max(out[node] ?? 0, n);  return out;}; const value = (c: GCounter) => Object.values(c).reduce((s, n) => s + n, 0); let us = increment({}, "us-east", 3);let eu = increment({}, "eu-west", 2);us = merge(us, eu); eu = merge(eu, us);console.log(value(us), value(eu)); // 5 5: replicas converge regardless of merge order
09

Complexity and performance

Convergence timems to seconds (typ.)

Longer during partitions.

CRDT mergeO(state size)

Commutative, associative, idempotent.

10

Trade-offs

Availability and latency vs anomalies

Eventual consistency keeps systems fast and available but pushes complexity into application logic.

Simplicity of LWW vs correctness

LWW is easy but loses data; merges and CRDTs preserve intent but constrain data models.

11

Variants and related techniques

Causal consistency

Stronger: preserves cause-effect order.

Strong eventual consistency

Replicas that received the same updates are identical immediately (CRDTs).

12

Common mistakes

  • Users not seeing their own changes.

    Fix: Provide read-your-writes via sticky routing or version tokens.

  • Relying on wall-clock timestamps for ordering.

    Fix: Clock skew reorders writes; use logical or hybrid clocks.

13

Interview questions

When is eventual consistency acceptable?

When temporary staleness does not break invariants or harm users: social counts, feeds, recommendations, search indexes, analytics. Not for balances, inventory decrements, or uniqueness constraints without extra safeguards.

How do you resolve conflicting writes?

Detect concurrency with versions or vector clocks, then use last-write-wins for simple fields, domain-specific merges (union of cart items), or CRDTs for counters and sets.

14

Practice problems

ProblemDifficultyWhat it trains
Implement a PN-counter CRDTMediumMerge rules.
Design a multi-region shopping cartHardConflict handling.