Skip to content
Low Level Design Mastery Logo
LowLevelDesign Mastery

PACELC Theorem

CAP + Latency = Real-world decisions

The CAP theorem tells us what happens during partitions, but what about normal operation? That’s where PACELC comes in.

Diagram

PACELC extends CAP by adding latency considerations:

If there’s a Partition (P): choose between Availability and Consistency
Else (E) (normal operation): choose between Latency and Consistency

Diagram

Key Insight: Even when there’s no partition, you still face a trade-off: fast responses (low latency) vs accurate data (consistency).


This is the CAP part we already know:

Diagram

Same as CAP: During partitions, choose CP or AP.


This is the new part PACELC adds:

Diagram

Key Insight: Even when everything works perfectly, you still choose between speed and accuracy.


When you prioritize low latency, you accept eventual consistency:

Diagram

Example: Reading from a local cache (fast, but might be outdated) vs reading from the primary database (slower, but always accurate).


When you prioritize consistency, you accept higher latency:

Diagram

Example: Asynchronous replication (fast, but eventual) vs synchronous replication (slower, but consistent).


Diagram

Choice: Most e-commerce sites choose low latency for product pages (cache) but consistency for checkout (database).


Diagram

Choice: Social media prioritizes low latency (read from nearby replica) over perfect consistency.


Diagram

Choice: Banking systems prioritize consistency over latency. Users accept slower responses for accurate data.


PACELC gives us four possible combinations:

Diagram

During partition: Choose availability
Normal operation: Choose low latency

Examples: DNS, CDN, most caching systems

Characteristics:

  • ✅ Always available
  • ✅ Fast responses
  • ❌ May serve stale data

During partition: Choose availability
Normal operation: Choose consistency

Examples: Cassandra (with tunable consistency), DynamoDB (with strong consistency reads)

Characteristics:

  • ✅ Available during partitions
  • ✅ Consistent during normal operation
  • ⚠️ Slower during normal operation

During partition: Choose consistency
Normal operation: Choose low latency

Examples: MongoDB (with strong consistency, but optimized for speed)

Characteristics:

  • ✅ Consistent during partitions
  • ✅ Fast during normal operation
  • ❌ May reject requests during partitions

During partition: Choose consistency
Normal operation: Choose consistency

Examples: Traditional relational databases (PostgreSQL, MySQL)

Characteristics:

  • ✅ Always consistent
  • ❌ Slower (synchronous replication)
  • ❌ May reject requests during partitions

Diagram

Example: An e-commerce system might:

  • Product pages: PA-EL (fast, cached)
  • Checkout: PC-EC (consistent, accurate)
  • Inventory: PC-EC (consistent, can’t oversell)

How PACELC choices affect your method design:

When prioritizing latency, use asynchronous patterns:

Low Latency: Async Operations
import asyncio
from typing import Optional
class LowLatencyService:
def __init__(self):
self._cache = {} # Local cache for fast reads
async def read(self, key: str) -> Optional[object]:
# Read from cache first (low latency)
if key in self._cache:
return self._cache[key] # Fast!
# Fallback to DB if not in cache
return await self._read_from_db(key)
async def write(self, key: str, value: object):
# Write to cache immediately (low latency)
self._cache[key] = value
# Replicate asynchronously (eventual consistency)
asyncio.create_task(self._replicate_async(key, value))

When prioritizing consistency, use synchronous patterns:

Consistency: Sync Operations
from threading import Lock
class ConsistentService:
def __init__(self):
self._data = {}
self._lock = Lock()
self._replicas = [] # List of replica nodes
def write(self, key: str, value: object) -> bool:
with self._lock:
# Write to primary synchronously
self._data[key] = value
# Replicate to all replicas synchronously (consistency)
for replica in self._replicas:
if not replica.set(key, value): # Wait for each
return False # Fail if any replica fails
return True # Only return success when all updated

Use this framework to choose your PACELC combination:

Diagram
Use CasePACELC ChoiceWhy
Bank balancePC-ECAccuracy > Speed
Product pagePA-ELSpeed > Perfect accuracy
CheckoutPC-ECAccuracy > Speed
Social feedPA-ELSpeed > Perfect accuracy
InventoryPC-ECAccuracy > Speed (can’t oversell)


Now that you understand consistency trade-offs, let’s explore how to maintain consistency across multiple operations:

Next up: Distributed Transactions — Learn how to coordinate multiple operations across distributed systems using 2PC, Saga pattern, and compensation.