PACELC
PACELC
Understand why the consistency trade-off applies during normal operation and not only during partitions, and how PACELC gives you a vocabulary for the decision your system makes on every single request.
Prerequisites
Recommended Knowledge
- The CAP theorem and its precise definitions
- Linearizability versus eventual consistency
- Quorum reads and writes
- Synchronous and asynchronous replication
- Leader-follower and multi-leader topologies
- Replica lag and staleness
- Latency percentiles and network round trips
- Partial failure and timeout ambiguity
The Gap CAP Leaves
CAP describes what happens during a network partition. That is a genuine constraint, but partitions are infrequent. A well-run system may spend almost all of its operating life with a perfectly healthy network.
This creates an awkward situation. CAP governs a rare condition, yet architects use it to justify decisions that affect every request, every day, whether or not anything has failed.
Unanswered Behavior the Rest of the Time
The PACELC Formulation
PACELC extends CAP by adding the normal-operation case. It reads as a conditional statement with two branches.
| Symbol | Meaning | Applies When |
|---|---|---|
| P | A network partition is occurring | Rarely |
| A | Availability is preferred | During a partition |
| C | Consistency is preferred | In either branch |
| E | Else, the network is healthy | Almost always |
| L | Latency is preferred | During normal operation |
Simple Analogy
A contract requiring two signatures is slow even when both parties are in the building. The delay is not caused by anyone being unreachable; it is the cost of requiring agreement at all. Removing the requirement makes things faster every day, not only on days someone is absent.
Why Consistency Costs Latency
A linearizable write cannot be acknowledged until enough replicas have durably recorded it. The acknowledgement therefore cannot arrive before the slowest required replica has replied.
Here \(Q\) is the set of replicas forming the write quorum. The write is bounded below by the round trip to the furthest member, which is a property of physics rather than implementation quality.
| Replica Placement | Dominant Cost | Practical Consequence |
|---|---|---|
| Same host | Memory and disk | Coordination cost negligible |
| Same rack | Local network | Sub-millisecond, rarely noticed |
| Same region, multiple zones | Inter-zone links | Small but measurable addition |
| Continental, multiple regions | Long-haul fibre | Clearly visible to users |
| Intercontinental | Speed of light | Often unacceptable for interactive writes |
The Four Classifications
Combining both branches yields four categories. Each describes a coherent design posture.
| Class | During Partition | Normal Operation | Typical Topology |
|---|---|---|---|
| PC/EC | Rejects the minority side | Pays coordination cost always | Consensus-replicated store |
| PC/EL | Rejects the minority side | Allows faster, weaker reads | Tunable quorum store |
| PA/EL | Continues serving both sides | Optimizes for low latency | Leaderless replication |
| PA/EC | Continues serving both sides | Coordinates when healthy | Uncommon, situational |
PC/EC Characteristics
- Simplest mental model for developers
- No conflict resolution required
- Predictable but higher write latency
- Unavailable to the minority partition
- Suits correctness-critical state
PA/EL Characteristics
- Lowest achievable latency
- Remains writable during partitions
- Requires conflict resolution logic
- Clients must tolerate staleness
- Suits high-volume tolerant workloads
Topology Determines Classification
A system's PACELC position is largely a consequence of how it replicates, not an independent choice layered on afterwards.
| Replication Model | Write Path | Resulting Tendency |
|---|---|---|
| Synchronous leader-follower | Leader waits for followers | EC, higher latency |
| Asynchronous leader-follower | Leader acknowledges immediately | EL, followers lag |
| Consensus replication | Majority must durably accept | PC/EC |
| Multi-leader | Any leader accepts locally | PA/EL with conflicts |
| Leaderless with low quorum | Few replicas must respond | PA/EL |
| Leaderless with strict quorum | Read and write sets overlap | PC/EC-leaning |
Tunable Systems and Per-Operation Position
Many datastores expose consistency as a request-level parameter. This means the classification is not fixed for the system but selected per operation.
const OPERATION_PROFILE = {
"order.create": {
writeConsistency: "quorum",
readConsistency: "quorum",
pacelc: "PC/EC",
rationale: "duplicate or lost orders are unacceptable"
},
"inventory.reserve": {
writeConsistency: "quorum",
readConsistency: "quorum",
pacelc: "PC/EC",
rationale: "overselling has direct financial cost"
},
"profile.read": {
writeConsistency: "quorum",
readConsistency: "local",
pacelc: "PC/EL",
rationale: "durable writes, fast reads, brief staleness tolerable"
},
"activity.record": {
writeConsistency: "one",
readConsistency: "local",
pacelc: "PA/EL",
rationale: "volume is high and individual loss is immaterial"
}
};
async function execute(operationName, payload) {
const profile = OPERATION_PROFILE[operationName];
if (!profile) {
throw new Error(
`Operation ${operationName} has no declared consistency profile`
);
}
return await datastore.execute(payload, {
writeConsistency: profile.writeConsistency,
readConsistency: profile.readConsistency
});
}
Intermediate Consistency Levels
The else-branch is not a binary between linearizable and eventual. Several intermediate guarantees provide useful properties at lower cost.
| Level | Guarantee | Relative Cost |
|---|---|---|
| Linearizable | Single-copy semantics, real-time ordering | Highest |
| Sequential | All nodes observe the same order | High |
| Bounded staleness | Lag never exceeds a stated limit | Moderate |
| Read-your-writes | A client always sees its own updates | Low to moderate |
| Monotonic reads | A client never moves backwards in time | Low |
| Eventual | Replicas converge if updates stop | Lowest |
async function readWithSessionGuarantee(key, session) {
const lastWriteVersion = session.versions.get(key);
if (!lastWriteVersion) {
return await datastore.readLocal(key);
}
const localValue = await datastore.readLocal(key);
if (localValue.version >= lastWriteVersion) {
return localValue;
}
return await datastore.readQuorum(key);
}
This pattern serves the fast local read in the common case and escalates to a coordinated read only when the local replica has not yet caught up with the client's own write.
Quantifying the Choice
The else-branch decision becomes concrete once you estimate what coordination costs in your specific deployment.
function estimateConsistencyCost(topology) {
const localReadMs = topology.localReadMs;
const quorumMembers = topology.replicaLatenciesMs
.slice()
.sort((a, b) => a - b)
.slice(0, topology.quorumSize);
const slowestInQuorum = quorumMembers[quorumMembers.length - 1];
const consistentReadMs = slowestInQuorum + topology.processingMs;
return {
localReadMs: localReadMs,
consistentReadMs: consistentReadMs,
additionalMs: consistentReadMs - localReadMs,
multiplier: (consistentReadMs / localReadMs).toFixed(1)
};
}
| Question | Why It Determines the Branch |
|---|---|
| What does coordination add per request? | Converts an abstract trade-off into a number |
| How long does replication typically lag? | Bounds the staleness a weak read may return |
| What is the harm of one stale read? | Distinguishes cosmetic from consequential |
| Would the user detect the inconsistency? | Session guarantees may suffice |
| Is the operation on a critical path? | Latency compounds across dependent calls |
| Can staleness be disclosed? | Informed clients can decide for themselves |
Latency Compounds Across Services
A single coordinated read may seem affordable in isolation. In a request that traverses several services, each consistency decision adds to a total the user experiences as one number.
A Worked Example
Consider a globally deployed commerce platform and how each operation lands within PACELC.
Payment Authorization — PC/EC
Coordination is required even when healthy, because a duplicate authorization is worse than a slower checkout. During a partition, the minority region refuses.
Inventory Reservation — PC/EC
Overselling creates fulfilment failures and refunds. The coordination cost is accepted as the price of correctness.
Order History — PC/EL
Writes are durable and coordinated, but reads are served from a local replica. A briefly incomplete history is acceptable, and the read volume is high.
Product Catalogue — PA/EL
Reads dominate overwhelmingly and content changes slowly. Local reads keep browsing fast, and partitions do not prevent customers from shopping.
Shopping Cart — PA/EL with Session Guarantees
Fast local access, but read-your-writes ensures a customer always sees the item they just added, which is the anomaly they would actually notice.
Activity Telemetry — PA/EL
Extremely high volume with negligible per-event value. Acknowledging on a single replica is appropriate.
Content and Sessions PA/EL
Disclosing the Choice
When the else-branch favours latency, clients receive data of unknown freshness. Stating which level was applied allows callers to make informed decisions.
{
"data": {
"productId": "product-501",
"price": 2499.00,
"available": true
},
"consistency": {
"branch": "else",
"levelApplied": "local-read",
"pacelcPosition": "PA/EL",
"replicaAsOf": "2026-09-24T05:20:14Z",
"estimatedStalenessMs": 340,
"upgradeAvailable": true
}
}
Useful Metadata
- Which consistency level actually applied
- The point in time the data reflects
- Estimated staleness at the moment of reading
- Whether a stronger read is available on request
- Whether the system is currently partitioned
Observing Both Branches
Signals Worth Tracking
- Write latency split by consistency level
- Read latency for local versus quorum paths
- Replica lag distribution, not the average
- Proportion of reads served locally
- Session-guarantee escalations to quorum reads
- Stale reads detected by version comparison
- Cross-region round-trip times
- Time spent partitioned versus healthy
- Conflict rate for weakly consistent operations
- Latency contribution per service on critical paths
Common Design Mistakes
Weak Reasoning
- Reasoning only about partition behavior
- Assuming consistency is free when healthy
- Applying one classification system-wide
- Treating the choice as strong or eventual only
- Ignoring accumulated latency across services
- Accepting datastore defaults unexamined
- Placing quorum members across distant regions carelessly
- Serving stale data without disclosure
- Never measuring actual replica lag
Strong Reasoning
- Considers both branches deliberately
- Quantifies coordination cost per deployment
- Assigns a position per operation
- Uses session guarantees where they suffice
- Budgets latency across the request path
- Configures consistency levels explicitly
- Places quorum members with latency in mind
- Returns staleness metadata to clients
- Monitors lag distribution continuously
System Design Interview Discussion
| Question | What Your Answer Should Cover |
|---|---|
| What does PACELC add to CAP? | The normal-operation latency trade-off |
| Why does the else-branch matter more? | It applies continuously, not only during failure |
| Where does this system sit? | Per-operation positions with reasoning |
| What does consistency cost you? | A concrete latency figure for your topology |
| Can you avoid the binary? | Session guarantees and bounded staleness |
| How does topology influence this? | Replication model determines classification |
| How do choices accumulate? | Latency budgets across the request path |
| How do clients know what they got? | Consistency metadata in responses |
Design Checklist
Production Checklist
- Declare a PACELC position for each operation
- Measure coordination cost in your actual topology
- Record replica lag distribution, not just the mean
- Reserve strong consistency for operations that need it
- Use session guarantees for user-visible anomalies
- Consider bounded staleness before full linearizability
- Place quorum members with latency in mind
- Avoid distant replicas in the critical write quorum
- Set an end-to-end latency budget per request path
- Attribute latency contribution per service
- Configure consistency explicitly rather than by default
- Return consistency metadata in responses
- Offer a stronger read option where useful
- Monitor both branches independently
- Test behavior under elevated replica lag
Knowledge Check
What does PACELC add to CAP?
An explicit else-branch describing the trade-off between latency and consistency during normal operation, which CAP does not address at all.
Why does consistency cost latency?
A linearizable operation cannot be acknowledged until the required replicas respond, so it is bounded below by the round trip to the slowest quorum member.
Why is PA/EC uncommon?
A system already willing to diverge during partitions gains little from paying full coordination cost when the network is healthy.
Why are session guarantees valuable?
They remove the anomalies users actually perceive, such as not seeing their own update, at far lower cost than global linearizability.
Why does topology matter?
The replication model largely determines the PACELC position, so consistency goals and replication design must be chosen together rather than independently.
Summary
PACELC extends CAP by acknowledging that the consistency trade-off does not disappear when the network is healthy. If a partition occurs, the system trades availability against consistency; else, it trades latency against consistency.
The else-branch is the more consequential half in practice, because partitions are rare while every request pays coordination cost. That cost has a physical floor set by the round trip to the slowest replica in the quorum, which distance alone can make prohibitive.
The four classifications follow largely from replication topology. Consensus replication tends toward PC/EC, asynchronous and leaderless models toward PA/EL, and tunable stores let the position be selected per request rather than fixed.
The decision is not binary. Bounded staleness, read-your-writes, and monotonic reads occupy useful middle ground, frequently removing the anomalies users would notice at a small fraction of the cost of full linearizability.
Key Takeaway
The else-branch is where you live. Quantify what coordination costs in your topology, assign a PACELC position per operation rather than per system, reach for session guarantees before full linearizability, budget latency across the whole request path, and tell clients which guarantee they actually received.