Guide · System design
CAP Theorem vs PACELC: The Latency Half CAP Leaves Out
25 min readUpdated By Saket Bhatnagar
Researched and drafted with AI, reviewed and edited by Saket Bhatnagar.
In short
- CAP theorem vs PACELC comes down to this: CAP covers only a network split, when copies of your data cannot reach each other. PACELC adds the normal day, when every copy costs you speed or freshness.
- CAP says that during a split, each side must either refuse requests to stay correct (consistency) or keep answering and risk being wrong (availability).
- PACELC reads: if there is a Partition (a split), choose Availability or Consistency; Else, choose Latency (how long one request takes) or Consistency. Splits are rare, but the else half applies to every request.
- Many databases let you pick per request. Cassandra and DynamoDB, two widely used databases that keep several copies, offer fast or fresh reads. On etcd, an open-source store, with replicas a 50 ms round trip apart, our fresh reads took 55 to 108 ms and local reads about 1 ms.
- Beginners can stop after the section that compares CAP and PACELC side by side. Engineers then get an etcd 3.4.30 drill you can run, why overlapping read and write groups can still return stale data, and a split-safe home-region design.
What goes wrong when two copies of your data stop talking?
Both copies can say yes to the same thing, such as the same room on the same night, because neither knows what the other just did. That risk, and the everyday cost of avoiding it, is what CAP theorem vs PACELC is about.
Picture a common setup. A homestay booking site runs its servers in two cloud regions, Mumbai and Hyderabad, so one region can fail without the site going down. The setup is made up, but the problem is real.
Each guest talks to the nearest region, and each region takes bookings into its own database. A background job copies every change to the other region, usually within a second.
Look at the arrow between the two databases in the diagram. It is the only thing that keeps the two copies in step.
Two regions, each taking bookings on its own
Drag to exploreEach region says yes to bookings by itself and tells the other region a moment later. Notice that nothing stops both regions from selling the same room.
Diagram connections:
- Guests to Region routing
- Region routing to Mumbai app servers (Nearest region)
- Region routing to Hyderabad app servers (Nearest region)
- Mumbai app servers to Mumbai database (Reads and writes)
- Hyderabad app servers to Hyderabad database (Reads and writes)
- Mumbai database to Hyderabad database (Copies changes, both ways)
- Guests: Browse and book on phone or laptop
- Region routing: Sends each guest to the nearest region
- Mumbai app servers: Searches and takes bookings
- Hyderabad app servers: Searches and takes bookings
- Mumbai database: Full copy of rooms and bookings
- Hyderabad database: Full copy of rooms and bookings
On a long-weekend Saturday, that copying link broke for 11 minutes (made up). Both regions stayed up and kept selling. A guest in Pune booked the last room at a homestay in Jibhi through Mumbai.
Two minutes later, a guest in Chennai booked the same room for the same nights through Hyderabad. When the link came back, the two databases disagreed about that room and 13 others. The team spent the weekend calling guests and paying for hotel rooms.
The team's first fix was the naive one. Every booking, and every availability check on the search page, now had to reach both regions before it answered. Double bookings stopped, but the search page went from about 180 milliseconds to about 420 (made up).
That leaves a puzzle. The link broke for 11 minutes, yet the site is now slower every minute of every day. That puzzle is the whole gap between CAP and PACELC.
Which words do you need before CAP and PACELC?
You need five words. Each one comes back many times below.
- Replica: one copy of the same data, kept on a different machine or in a different region. Copying data between replicas is called replication.
- Network partition, or split: the servers are still running, but messages between some of them are lost. The broken Mumbai to Hyderabad link was a partition.
- Latency: how long one request takes, from the moment it is sent to the moment its answer arrives. It is measured in milliseconds (ms), thousandths of a second.
- Round trip: one message out and its reply back. Waiting for another region costs at least one round trip.
- Stale read: a read that returns an older value because the newest write has not reached that replica yet.
What does the CAP theorem actually say?
The CAP theorem says that when a network split stops some servers from talking, a replicated system cannot be both fully consistent and fully available. During the split, it must give up one of them.
Eric Brewer first described the idea in 1998 and presented it as a conjecture at PODC 2000, a conference on distributed computing. In 2002, Seth Gilbert and Nancy Lynch proved a formal version. Most confusion about CAP comes from reading its three words loosely.
- Consistency (C): every read sees the latest completed write, as if there were only one copy. The formal name is linearizability. In the scenario, both regions would agree that the Jibhi room is taken.
- Availability (A): every request that reaches a server that has not crashed gets a real response, not an error. Mumbai answers even when it cannot hear Hyderabad.
- Partition tolerance (P): the system keeps its promises even when the network loses messages between servers.
Across real networks, you do not get to opt out of splits. Cables get cut, routers get misconfigured and whole regions go dark. So the real choice is what each side does while a split lasts.
The proof uses these strict meanings, on a single data item that clients read and write. A system can still offer weaker promises during a split, such as reads that may be a little old.
A mithai shop with two branches
Picture a mithai shop with two branches across town. They share one stock count of kaju katli by phone. One box is left, and a customer at each branch wants it. Then the phone line goes dead.
Each branch now has two honest options. It can refuse to sell the last box until the line is back, which keeps the count right but turns a customer away. Or it can sell now and risk that the other branch also sold it.
- Each branch maps to a replica, and the shared stock count maps to the data.
- The phone line maps to the network, and the dead line maps to a partition.
- Refusing to sell maps to choosing consistency. Selling anyway maps to choosing availability.
Where the picture breaks: a shopkeeper knows the line is dead. A server only sees replies that are late, so it cannot tell a dead link from a slow one.
Why is pick two of three the wrong way to read CAP?
Pick two of three is misleading because the choice only exists during a partition. When the network is healthy, nothing in CAP stops a system from being both consistent and available.
Brewer said this himself in a 2012 article, CAP Twelve Years Later. He wrote that the two of three framing was always misleading because it tended to oversimplify the tensions. He added that partitions are rare, so CAP should allow perfect C and A most of the time.
Daniel Abadi made the same point the same year. He wrote that many designers wrongly conclude that CAP restricts a system during normal operation. In his words, CAP only posits limits in the face of certain types of failure.
Brewer also gave a practical view of a split. In practice, he wrote, a partition is a time limit on communication. When a server cannot get a reply in time, it must either cancel the operation and lose availability, or go ahead and risk inconsistency.
So the booking site need not give up correctness all year to survive 11 bad minutes. But CAP cannot explain why the naive fix slowed every normal minute.
What is PACELC?
PACELC describes a replicated database with two choices instead of one. If there is a Partition, it picks Availability or Consistency. Else, on a normal day, it picks Latency or Consistency.
Daniel Abadi proposed it in the February 2012 issue of IEEE Computer, and it is pronounced pass-elk. The else half is the part the naive fix ran into.
Back at the mithai shop, it is an ordinary Diwali evening. The phone works, but each call to the other branch takes a minute, and the queue is long.
The branch can call before every sale, so the count is always right, but every customer waits an extra minute. Or it can sell straight away and phone the count across later. That is fast, and once in a while the last box is sold twice.
Here is the whole idea as a decision tree. Follow the No arrow from the first question, because that is the path almost every request takes.
PACELC as two questions
Drag to exploreOnly the top branch is CAP. Notice that the bottom branch runs on every normal request, so its cost shows up all year.
Diagram connections:
- A read or write arrives to Is the network split?
- Is the network split? to Answer anyway or refuse? (Yes)
- Is the network split? to Fast reply or fresh data? (No)
- Answer anyway or refuse? to PA: answer locally (Stay up)
- Answer anyway or refuse? to PC: refuse or wait (Stay correct)
- Fast reply or fresh data? to EL: nearest copy, now (Fast)
- Fast reply or fresh data? to EC: coordinate first (Fresh)
- A read or write arrives: Say, a booking for the Jibhi room
- Is the network split?: Rare: minutes a year in the scenario
- Answer anyway or refuse?: The CAP choice
- PA: answer locally: Stays up, may be wrong or stale
- PC: refuse or wait: Stays correct, some requests fail
- Fast reply or fresh data?: The choice CAP leaves out
- EL: nearest copy, now: Low latency, may be a little old
- EC: coordinate first: Fresh, pays at least one round trip
Abadi argues that availability and latency are closely linked. An unavailable system, in his words, essentially provides extremely high latency. A reply after several seconds is as useless to a guest as no reply at all.
CAP theorem vs PACELC: what is the difference?
The CAP theorem covers only what happens during a network split, while PACELC adds what you trade on normal days: latency against consistency. CAP is a proved result about failures, and PACELC is a way to describe design choices.
| CAP theorem | PACELC | |
|---|---|---|
| What it is | A proved impossibility result | A way to describe a design, not a proof |
| When it applies | Only during a partition | During a partition and on every normal request |
| The trade-off | Availability or consistency | Availability or consistency, then latency or consistency |
| How often it bites | Rarely, during failures | All the time, once data is copied |
| Labels it gives | CP or AP | PA/EL, PC/EC, PA/EC or PC/EL |
| What it explains in the scenario | The 14 double bookings | Why the naive fix slowed every search |
Abadi argues that the latency trade-off has had a more direct influence on several well-known databases than CAP itself. He calls ignoring it a major oversight, because it is present all the time, not only during splits.
Why does copying data force a choice between latency and consistency?
Copying data forces the choice because a write cannot reach every replica instantly. Either you wait for other replicas to confirm before answering, which costs time, or you answer first and let the copies catch up, which risks stale reads.
You replicate for availability: if one machine or region dies, another copy still has the data. Abadi's point is that the mere possibility of failure forces replication, so the trade-off follows you even when nothing is failing.
Abadi notes there are only three ways to send an update to replicas. Each one has a latency or consistency cost.
- Send it to all replicas at once. Without an agreement step, each replica may apply updates in a different order and drift apart. Agreeing on an order takes time.
- Send it to one agreed leader first. The leader orders updates and copies them out. A faraway writer waits for the leader, and reads from other copies can be stale.
- Send it to any single replica first, often the nearest. It is fast, but two replicas can accept clashing updates at the same moment, which is exactly the Jibhi room.
The cost grows with distance. Abadi notes that network latency inside one data centre is small, so waiting is cheap there. For replication across a wide area network, he writes, there is no way around the consistency and latency trade-off.
Synchronous replication means the writer waits until other replicas confirm. Asynchronous replication means the writer answers first and copies later. The scenario started fully asynchronous, which caused the double bookings, and the naive fix made everything synchronous, which slowed every request.
How are real databases classified under PACELC?
Abadi's 2012 article labels several well-known systems by their default settings at that time. He also notes that once a system gives up consistency during splits, it makes sense to give it up on normal days too, for speed.
| System | Label | What it means |
|---|---|---|
| Dynamo, Cassandra, Riak | PA/EL | Stays up in a split and favours speed on normal days, with settings to ask for more consistency |
| VoltDB/H-Store, Megastore | PC/EC | Fully transactional, pays in availability and latency to stay consistent |
| BigTable, HBase | PC/EC | Keeps consistency in both cases |
| MongoDB (2012 behaviour) | PA/EC | Consistent on normal days; in a split, writes on a cut-off primary can diverge until fixed by hand |
| PNUTS | PC/EL | Fast, possibly stale reads on normal days, gives up some availability in a split |
PC/EL looks odd at first, as if PNUTS became more consistent during a split. Abadi says that reading is wrong. PC there means the system does not drop below its normal consistency during a split; it gives up availability instead.
Treat these labels as a 2012 snapshot, not a verdict. Products change across versions, and many now let you choose per request, as the next two show.
Cassandra: choose per request
Apache Cassandra offers a per-operation trade-off through consistency levels. ONE waits for one replica, QUORUM waits for a majority of replicas, and ALL waits for every replica. Its docs say writes are always sent to all replicas; the level only sets how many replies the coordinator waits for.
The coordinator is the node that handles your request. With several data centres, LOCAL_QUORUM waits for a majority in the coordinator's own data centre, while EACH_QUORUM waits for a majority in every data centre. The docs say ONE or LOCAL_ONE can improve throughput, latency and availability.
DynamoDB: fast reads by default, fresh reads on request
Amazon DynamoDB reads are eventually consistent by default. Eventually consistent means a read may miss a very recent write, but the same read repeated after a short time should return it. Setting ConsistentRead to true returns the latest successful write, and the docs say eventually consistent reads cost half as much.
Its multi-Region global tables show the else half clearly. The default mode, multi-Region eventual consistency, copies changes asynchronously, typically within a second. It settles clashing writes to the same item with last writer wins, which keeps the change with the latest internal timestamp.
The multi-Region strong consistency mode copies each change to at least one other Region before the write returns. The docs say it has higher write and strongly consistent read latency, and it must run in exactly three Regions. Those can be three replicas, or two replicas and a witness, which holds the data but serves no reads or writes. All of this is as of 19 October 2026.
Do quorums give you consistency for free?
No. A quorum gives you overlap, which lets a read find the latest write, but overlap is not enough on its own. A quorum is a minimum number of replies: with N replicas, a write waits for W of them and a read asks R of them.
If R plus W is greater than N, every possible read set shares at least one replica with every possible write set. You can check that claim yourself by trying every combination.
from itertools import combinations
def always_overlap(n, w, r):
"""True if every set of r replicas shares one with every set of w."""
nodes = range(n)
return all(set(ws) & set(rs)
for ws in combinations(nodes, w)
for rs in combinations(nodes, r))
for n, w, r in [(3, 2, 2), (3, 1, 1), (3, 1, 3), (5, 3, 3), (5, 2, 3)]:
rule = "R+W>N " if r + w > n else "R+W<=N"
print(n, w, r, rule, always_overlap(n, w, r))On Python 3.13 it prints five lines. The three R+W>N lines end in True, and the two R+W<=N lines, 3 1 1 and 5 2 3, end in False. Overlap holds exactly when R plus W is greater than N.
Abadi warns that a quorum protocol alone does not reach the strict consistency of Gilbert and Lynch, even when R plus W is greater than N. Here is one way it fails on a plain quorum store with no repair step, with N of 3, W of 2 and R of 2.
- A write of BOOKED has reached replica A, but not yet B or C. The writer is still waiting for its second reply.
- Reader 1 asks A and B, takes the newest value, and sees BOOKED.
- Reader 2 starts after reader 1 has finished, asks B and C, and sees free.
A later read saw an older value than an earlier one, which a single copy would never do. Cassandra's docs describe the same kind of effect: when a write fails to reach a quorum, it may be visible in one read and then disappear in the next.
Cassandra guards against this case with blocking read repair, the default. A read that finds stale copies fixes them before it answers, which the docs call monotonic quorum reads. Setting the table option read_repair to NONE gives that up.
What does the else half cost on a real database?
On etcd 3.4.30 in our test, a fresh read took about 55 to 108 ms, while a read from the local copy took about 1 ms. The replicas were a 50 ms round trip apart, and that wait made up almost all of the gap.
etcd is an open-source, strongly consistent key-value store that keeps its replicas in step with the Raft consensus algorithm. Its docs say reads are linearizable by default, and a request can ask for a serializable read instead.
A serializable read answers from the member's own copy, so it may be stale but skips the coordination cost. A linearizable read checks with a majority first.
We ran three members on one Linux machine. A small proxy added 25 ms each way between members, a 50 ms round trip, like two far-apart regions. Requests from the client were not delayed. Data sat on a RAM disk, so write times leave out disk sync time.
| Request | Sent to | Median latency | PACELC choice |
|---|---|---|---|
| Serializable read | Any member | About 1.2 ms | EL: local copy, may be stale |
| Linearizable read (default) | Leader | 54.8 ms | EC: one round trip to a majority |
| Linearizable read (default) | Follower | 108.1 ms | EC: two round trips |
| Write | Leader | 54.8 ms | EC: a majority must store it |
| Write | Follower | 107.8 ms | EC: forwarded to the leader first |
The leader is the member that orders all writes; the others are followers. A linearizable read sent to a follower cost two round trips in our run. That matches the read-index method in the Raft dissertation: the follower asks the leader, and the leader confirms with a majority.
With no added delay, the same linearizable reads took 2.1 to 2.6 ms. etcd's docs say linearizable requests carry a cost but give no figures. The numbers above are our measurements, undocumented as of 19 October 2026; pin your version before relying on them.
Try the partition half yourself
You can see the partition half on a Linux machine with etcd 3.4.30 installed, the only version we tested. Start three members, write a key, then stop two members so the third hears nobody.
CL=m1=http://127.0.0.1:12380,m2=http://127.0.0.1:22380,m3=http://127.0.0.1:32380
for i in 1 2 3; do
etcd --name m$i --data-dir /tmp/pacelc-m$i \
--listen-client-urls http://127.0.0.1:${i}2379 \
--advertise-client-urls http://127.0.0.1:${i}2379 \
--listen-peer-urls http://127.0.0.1:${i}2380 \
--initial-advertise-peer-urls http://127.0.0.1:${i}2380 \
--initial-cluster $CL > /tmp/pacelc-m$i.log 2>&1 &
echo $! > /tmp/pacelc-m$i.pid
done
sleep 3
etcdctl --endpoints=127.0.0.1:12379 put room/jibhi-7 free
kill $(cat /tmp/pacelc-m2.pid) $(cat /tmp/pacelc-m3.pid)
time etcdctl --endpoints=127.0.0.1:12379 get room/jibhi-7 --consistency=s
time etcdctl --endpoints=127.0.0.1:12379 get room/jibhi-7
time etcdctl --endpoints=127.0.0.1:12379 put room/jibhi-7 bookedExpect OK from the put. The serializable get then prints room/jibhi-7 and free, and time shows about 0.02 s (real 0m0.017s in our run). The plain get and the second put each print Error: context deadline exceeded after about 5 s, which is etcdctl's default command timeout. Just before each error, etcdctl 3.4.30 also prints a JSON warning line saying retrying of unary invoker failed, which is expected.
In a second run, we cut one member off with firewall rules while the other two kept working. The majority wrote BOOKED. The cut-off member still answered a serializable read with free, a stale value, in 1.4 ms, and refused fresh reads and writes.
So etcd's defaults behave as PC/EC in our tests, and serializable reads are a per-request EL choice. That is our label, not one from Abadi's article.
How do you choose between latency and consistency for each kind of data?
You choose per kind of data by asking what a stale or doubled answer would cost. Where a wrong answer costs money or trust, pay the latency. Where it costs little, take the speed.
The team listed what the booking site stores and what a stale answer would mean for each. Only one thing truly needed both regions to agree: the room calendar, which says which nights of which room are booked.
| Data | During a split | On a normal day | Label |
|---|---|---|---|
| Room calendar (bookings) | Refuse bookings it cannot confirm | Wait for the homestay's home region, about 25 ms extra | PC/EC |
| Search results and prices | Serve the local copy | Nearest copy, maybe a few seconds old | PA/EL |
| Reviews and photos | Serve the local copy | Nearest copy | PA/EL |
| Guest wishlists | Accept saves locally | Nearest copy, merge later | PA/EL |
The search page can show slightly old availability, because the booking step checks again. A guest might see a room as free, tap Book, and hear that it just went. That is annoying, but nobody turns up to a room that is not there.
The team wrote the choices down as code, so nobody has to guess. In the snippet, local_replica and replica_in stand in for real database clients. The consistent flag asks the replica for the latest write only.
# What each kind of data picks: (during a split, on a normal day)
PACELC = {
"room_calendar": ("C", "C"), # PC/EC: never sell a night twice
"search_cards": ("A", "L"), # PA/EL: fast, may be seconds old
"reviews": ("A", "L"),
"wishlists": ("A", "L"),
}
def read(kind, key, home_region):
_, normal_day = PACELC[kind]
if normal_day == "L":
return local_replica.get(key) # fast, maybe stale
return replica_in(home_region).get(key, consistent=True) # fresh, slowerThe table turns a vague promise into a rule each engineer can read. Only the room calendar pays the cross-region wait, so search, reviews and wishlists go back to their old speed.
How can one system be fast on normal days and safe during a split?
Give each piece of critical data one home, and decide it only there. Reads elsewhere stay fast, and only writes to that data pay the trip to its home.
The team gave every homestay a home region, the region that owns its room calendar. Homestays near Manali and Kullu live in Mumbai, and homestays near Shimla and Kinnaur live in Hyderabad. A booking is decided only in the homestay's home region, so two regions can never both say yes.
Here is a booking that lands in the wrong region. Follow the steps from the guest's tap. The question box is where Brewer's idea of a partition as a time limit becomes real code.
A Hyderabad guest books a Mumbai-homed room
Drag to exploreNotice that only the home region decides. If it does not reply within 300 ms (made up), the guest is asked to retry instead of getting a second yes.
Diagram connections:
- Guest taps Book to Look up the home region
- Look up the home region to Forward the booking
- Forward the booking to Reserve the room-nights
- Reserve the room-nights to Reply within 300 ms?
- Reply within 300 ms? to Show booking confirmed (Yes)
- Reply within 300 ms? to Ask the guest to retry (No reply)
- Guest taps Book: Guest → Hyderabad app
- Look up the home region: Hyderabad app → homestay record
- Forward the booking: Hyderabad app → Mumbai app
- Reserve the room-nights: Mumbai app → Mumbai database
- Reply within 300 ms?: Mumbai app → Hyderabad app
- Show booking confirmed: Hyderabad app → Guest
- Ask the guest to retry: Hyderabad app → Guest
Here is the same flow in Python. The helpers reserve_here, forward_to_home and queue_for_retry are stand-ins. The first books inside one all-or-nothing database transaction, and the second raises TimeoutError if no reply comes. The third saves the booking id so a job can try again later.
HOME_TIMEOUT = 0.3 # seconds to wait for the homestay's home region
def book(stay, room, nights, guest, booking_id):
if stay.home_region == THIS_REGION:
return reserve_here(room, nights, guest, booking_id)
try:
return forward_to_home(stay.home_region, room, nights, guest,
booking_id, timeout=HOME_TIMEOUT)
except TimeoutError:
# Partition mode: choose consistency, never decide here
queue_for_retry(stay.home_region, booking_id)
return ("We could not confirm this room yet. "
"We will message you, or you can retry.")The except branch carries the design. It is the PC choice: when the home region is silent, Hyderabad refuses to decide. A timeout does not tell you whether Mumbai reserved the room, so the booking id matters.
Sending the same booking id on a retry lets Mumbai spot a repeat instead of booking twice. This only works if Mumbai stores each booking id and checks it before reserving.
This design is PC/EC for room calendars, but only some bookings pay the extra wait. A guest whose nearest region is the homestay's home region books with no cross-region trip at all. During a split, each region can still sell its own homestays.
Brewer described three steps for living with partitions: detect the split, enter a partition mode that limits some operations, and recover once the link returns. Here, a timeout detects the split, refusing cross-region bookings is the partition mode, and a job replays the queued booking ids afterwards.
After the change, the search page went back to about 180 milliseconds, and no room was sold twice (made up). The team pays for safety only where it matters.
How do you explain CAP and PACELC in a system design interview?
Explain CAP as the failure case and PACELC as the everyday case, then choose for each kind of data with a reason.
Ask about replicas and regions
Find out whether data is copied across machines or regions. Without copies there is no trade-off to discuss, only single points of failure.
Define the three CAP words
Say consistency means every read sees the latest write, availability means every working server answers, and a partition is a network split.
Say what happens during a split
For each kind of data, choose: refuse and stay correct, or answer and repair later. Name what repair means, such as merging or refunding.
Say what happens on a normal day
Choose fast or fresh for each read path. Give a rough number, such as one extra cross-region round trip per booking.
Give the label and the knob
Call it PA/EL or PC/EC, then name the setting that enforces it: a consistency level, a consistent read flag, or a home region.
Close with recovery
Explain how the system notices a split, what it limits during the split, and how it repairs data once the link returns.
Flavours of consistency such as read-your-writes belong to a separate guide on consistency models. For CAP and PACELC questions, the two halves and a clear choice per kind of data are enough.
Questions people ask
- Is the CAP theorem still relevant?
- Yes, but for a narrower question than many people think. CAP tells you that during a network split, a replicated system must choose between strict consistency and availability. It says nothing about normal days, which is why PACELC adds the latency half. Use both together when you describe a design.
- Can a distributed system be CA?
- Only if you bet that splits will not happen. Brewer says choosing CA should mean a split is far less likely than other failures, as many teams assume inside one data centre. Splits are still possible there, and if one happens, a CA system must fall back to C or A. So the useful question is not whether you are CA, but what your system does when a split happens.
- Is PACELC a theorem?
- No, PACELC is a way of describing design choices, not a proved theorem. Abadi proposed it in 2012 to add the latency and consistency trade-off to CAP. The CAP half rests on a formal proof, while the else half describes a cost that comes from copying data over a network.
- What does PA/EL mean?
- PA/EL means the system chooses availability during a partition and low latency on normal days. In both cases it gives up some consistency, so reads may be stale. Abadi's 2012 article put the default settings of Dynamo, Cassandra and Riak in this group, though they offer settings for more consistency.
- Does strong consistency always make a system slow?
- No, the cost depends mostly on distance. Inside one data centre, waiting for another replica adds little. Across regions, each consistent write or read waits for at least one long round trip. In our etcd test with a 50 ms round trip, a fresh read cost 55 to 108 ms against about 1 ms.
- What is eventual consistency?
- Eventual consistency means replicas may disagree for a short time, but they catch up and agree if writes stop. A read might miss a very recent write. It suits data where a few seconds of staleness is harmless, such as reviews, likes or photos on a listing page.
Sources and further reading
- Consistency Tradeoffs in Modern Distributed Database System Design, IEEE Computer, February 2012 (Abadi)
- CAP Twelve Years Later: How the Rules Have Changed (Brewer, 2012, republished by InfoQ)
- Brewer's Conjecture and the Feasibility of Consistent, Available, Partition-Tolerant Web Services (Gilbert and Lynch, 2002)
- Apache Cassandra documentation: Dynamo architecture and tunable consistency
- Apache Cassandra documentation: Read repair
- Amazon DynamoDB Developer Guide: Read consistency
- Amazon DynamoDB Developer Guide: How global tables work
- etcd v3.4 documentation: KV API guarantees (linearizable and serializable reads)
- Consensus: Bridging Theory and Practice, section 6.4 on read-only queries (Ongaro, Raft dissertation)