Apache Cassandra
Lightweight Transactions (LWT) & Compare-and-Set
Understand how Cassandra achieves linearizable compare-and-set semantics despite its eventually consistent design.
Cassandra writes without checking anything first. That is why writes are fast, and why "insert this username only if nobody has it" is not an ordinary write.
A normal Cassandra write is like shouting an update to everyone in the room without waiting to see if it's already been changed. An LWT is like calling a formal meeting, taking attendance, checking the current state, voting on whether to accept the change, and only then confirming it — much slower, but guarantees no conflicting change slips through.
Key Concepts
1
Why a read-then-write does not work. The obvious approach:
2
SELECT * FROM users WHERE username = 'asha'; -- empty
INSERT INTO users (username, ...) VALUES ('asha', ...);3
Two clients can run the SELECT at the same moment, both see nothing, and both insert. The second write
silently overwrites the first. No error, one account lost.
SELECT
4
Lightweight transactions close that gap. The condition is checked and the write applied as one
indivisible step:
5
INSERT INTO users (username, email) VALUES ('asha', 'a@x.com') IF NOT EXISTS;
UPDATE orders SET status = 'SHIPPED' WHERE id = 7 IF status = 'PACKED';6
The response tells you whether it applied. Two concurrent attempts: exactly one gets applied = true.
applied = true
7
How, and why it costs so much. Cassandra runs Paxos between the replicas — a round to propose and
gather promises, a round to accept, then the write and a commit round.
8
normal write: coordinator -> replicas 1 round trip
LWT: propose / promise
read current value
accept / accepted
commit 4 round trips9
So an LWT is roughly four times the latency of a normal write, and the rounds are sequential. Under
contention it is worse: competing proposals interfere and retry, so throughput collapses exactly when
several clients want the same row — which is precisely when you reach for it.
10
One partition only. The consensus is per partition. You cannot make a conditional change across two
partitions atomically, so LWTs are not a way to build multi-row transactions.
11
Where they earn their cost. Uniqueness on a key, a distributed lock, leader election, a state machine
that must not skip a step. All are rare writes where being wrong is expensive.
12
Where they do not. Any normal write with an IF bolted on out of caution. A common and costly mistake
is putting IF NOT EXISTS on every insert "to be safe" — that makes every write four times slower to
prevent something that was never a problem, since an overwrite with identical data is harmless.
IFIF NOT EXISTS
13
The conditional row must be the one you are protecting. IF NOT EXISTS on users_by_email guarantees
email uniqueness only if email is that table's partition key. Applying it to a table keyed by user_id
guarantees nothing about emails at all.
IF NOT EXISTSusers_by_emailemailuser_id
14
What the interviewer is probing.1. "What does IF NOT EXISTS actually do?" Probing: the mechanism. Stalls: "A check." *Moves
up:* runs Paxos across replicas to agree, which is why it is called lightweight relative to a full
transaction but is heavy for Cassandra.
15
2. "What is the performance cost?" Probing: the number worth knowing. Stalls: "Small."
Moves up: roughly four round trips instead of one, so it is many times slower — reserve it for
genuine uniqueness needs.
16
3. "What consistency does it use?" Probing: the detail. Stalls: "The usual." Moves up:
SERIAL or LOCAL_SERIAL, which is a separate setting from the normal consistency level.
17
4. "When is LWT the wrong answer?" Probing: the design pressure. Stalls: "Never." *Moves
up:* when used for ordinary writes — if your model needs many compare-and-set operations, Cassandra
may be the wrong store.