# PACELC Theorem

> CAP extended — if Partition (P), trade off Availability (A) vs Consistency (C); Else (E), trade off Latency (L) vs Consistency (C).

- **Category**: Trade-offs
- **Subcategory**: Distributed Systems
- **Canonical URL**: https://designpattern.fyi/trade_offs/pacelc-theorem/

---

## Description
**Intent**: Extend CAP theorem to handle normal operation trade-offs, not just failure scenarios. PACELC says: in case of Partition (P), choose between Availability (A) and Consistency (C); Else (E), when running normally, choose between Latency (L) and Consistency (C).

**Context**: CAP only addresses what happens during network failures. But in normal operation, you still face trade-offs. Strong consistency requires synchronous replication, which adds latency. Eventual consistency allows asynchronous replication, reducing latency but risking stale reads. PACELC captures both failure-time and run-time trade-offs.

**Solution**: Design your system for both scenarios. During partitions, decide AP vs. CP based on business requirements. During normal operation, decide EL vs. EC based on latency tolerance. Many systems choose EL (low latency, eventual consistency) for most operations, with EC paths for critical operations requiring strong consistency.



## Use Cases
Social media feed choosing EL during normal operation for low latency, AP during partitions for availability. Banking system choosing EC during normal operation for consistency, CP during partitions to prevent financial errors. Real-time bidding choosing EL for latency-critical auctions, with conflict resolution for rare inconsistencies.



## Implementation Example

```javascript
// PACELC in practice: Different paths for partition vs. normal operation

class PACELCDatabase {
  async write(key, value, consistency = 'eventual') {
    if (this.isPartitioned()) {
      // Partition mode: PAC — Availability vs. Consistency
      if (consistency === 'strong') {
        throw new Error("Unavailable: partition mode, cannot ensure consistency");
      }
      // AP: Write locally, replicate asynchronously
      this.writeToLocal(key, value);
      this.replicateAsync(key, value);
    } else {
      // Normal mode: ELC — Latency vs. Consistency
      if (consistency === 'strong') {
        // EC: Synchronous replication, higher latency
        await this.replicateSync(key, value);
      } else {
        // EL: Asynchronous replication, lower latency
        this.writeToLocal(key, value);
        this.replicateAsync(key, value);
      }
    }
  }
  
  async read(key, consistency = 'eventual') {
    if (this.isPartitioned()) {
      if (consistency === 'strong') {
        throw new Error("Unavailable: partition mode, cannot ensure consistency");
      }
      return this.readFromLocal(key); // May be stale
    } else {
      if (consistency === 'strong') {
        return await this.readFromQuorum(key); // EC: Higher latency
      } else {
        return this.readFromLocal(key); // EL: Lower latency
      }
    }
  }
}

// Usage examples
await db.write('user:123', data, 'strong'); // EC path
await db.write('feed:456', post, 'eventual'); // EL path

```



## Trade-offs


### Advantages

- More complete than CAP — addresses both failure and normal operation scenarios

- Realistic for production systems — latency matters even when everything works

- Guides system design for both happy path and failure scenarios

- Helps explain why "eventually consistent" systems can still have latency issues




### Considerations & Drawbacks

- More complex mental model than simple CAP — four combinations instead of two

- Still binary in each dimension — real systems have tunable consistency levels

- Does not address throughput trade-offs, only latency vs. consistency

- Less widely known than CAP — harder to communicate with stakeholders







