Glossary

Eventual Consistency

Eventual consistency is a consistency model where, after all updates stop, all replicas of a distributed system will eventually hold the same data — but reads may return stale data in the window between a write and full propagation.

Explanation

In a distributed system with multiple replicas, writes must propagate to all copies. Strong consistency means no replica returns data until all have the update — every read sees the latest write. Eventual consistency relaxes this: writes are acknowledged when they reach one (or a quorum of) replicas; propagation to the rest happens asynchronously. In the meantime, different replicas may return different values — but given no new writes, they will converge. The CAP theorem makes this explicit: during a network partition, an eventually consistent system continues serving requests with potentially stale data (choosing Availability), while a strongly consistent system refuses requests until the partition heals (choosing Consistency). Real examples: DNS propagation (a record change takes minutes to hours to propagate globally), social media likes (the displayed count lags the actual count by seconds), read replicas (PostgreSQL replicas are typically milliseconds to seconds behind the primary), and CDN caches (updates take up to TTL to propagate to all edge nodes). Handling eventual consistency: don't immediately read from a replica after writing (use primary for reads after writes, or return the known-good value from cache), handle conflicts with last-write-wins or CRDTs, and design for idempotency so replaying updates is safe.

Code Example

javascript
// Handling eventual consistency: read-after-write problem

async function updateUserAndRespond(userId, data) {
  // Write goes to primary
  await primaryDb.query(
    'UPDATE users SET name = $1 WHERE id = $2',
    [data.name, userId]
  );

  // BAD: reading from replica may return stale data (replication lag)
  // const user = await replicaDb.query('SELECT * FROM users WHERE id = $1', [userId]);

  // GOOD option 1: read from primary right after write
  const user = await primaryDb.query(
    'SELECT * FROM users WHERE id = $1', [userId]
  );

  // GOOD option 2: construct response from known state (no extra query)
  const updatedUser = { ...existingUser, ...data };

  // GOOD option 3: flag to use primary for N seconds
  await redis.setEx(`use-primary:${userId}`, 5, '1');

  return user.rows[0];
}

// Read path: check flag
async function getUser(userId) {
  const usePrimary = await redis.get(`use-primary:${userId}`);
  const db = usePrimary ? primaryDb : replicaDb;
  return db.query('SELECT * FROM users WHERE id = $1', [userId]);
}

Why It Matters for Engineers

Eventual consistency bugs are among the hardest to diagnose: they only manifest during replication lag (usually milliseconds — rare in tests, common at scale) and produce intermittent incorrect behavior. Understanding the pattern prevents shipping these bugs and explains their root cause when they occur. Eventual consistency also frames important architectural choices: when SQL's strong consistency is required (financial transactions, inventory) vs. when eventual consistency is acceptable (social counts, analytics). Getting this distinction wrong causes either correctness bugs (using eventual consistency where strong consistency is needed) or unnecessary complexity (requiring strong consistency where eventual would do).

Related Terms

CAP Theorem · Database Sharding · Cache · ACID

Learn This In Practice

Go deeper with the full module on Beyond Vibe Code.

Systems Design Fundamentals → →