Skip to content
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.

PACELC extends CAP: CAP covers behavior during partitions, PACELC covers both partitions and normal operation

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

PACELC splits every system into two choices: availability or consistency during a partition, latency or consistency otherwise

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:

PACELC partition branch: a network partition forces rejecting requests (CP) or serving requests with weaker consistency (AP)

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


This is the new part PACELC adds:

PACELC normal-operation branch: low latency reads from a local cache with eventual consistency versus accurate reads from the primary

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


When you prioritize low latency, you accept eventual consistency:

Read latency trade-off: a local cache answers in 10ms but may be stale, the primary database answers in 100ms but is always accurate

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:

Write latency trade-off: async write returns in 10ms with eventual consistency, sync write updates all replicas in 100ms

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


E-commerce product page: serving info, price and reviews from cache takes 30ms total versus 150ms from the database

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


Social media feed: reading from a local replica in 20ms is the typical choice over reading from the primary in 100ms

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


Bank balance check: a possibly wrong cached balance is not acceptable, so the read goes to the primary at 100ms

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


PACELC gives us four possible combinations:

Four PACELC combinations with examples: PA-EL for DNS and CDN, PA-EC for Cassandra, PC-EL for MongoDB, PC-EC for traditional RDBMS

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

Tuning PACELC per operation: normal reads use PA-EL from cache, while writes and critical reads use PC-EC from the primary

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:

💡 Tip: Click dropdown to switch between languages
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:

💡 Tip: Click dropdown to switch between languages
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:

PACELC decision tree: accuracy critical leads to PC-EC or PC-EL, speed critical to PA-EL or PC-EL, otherwise balance with PA-EC
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.