Cassandra defaults to eventual consistency because strong consistency requires coordination between replicas, and coordination costs latency and availability. At its default consistency level of ONE, a read returns the first replica to respond, which may not have the latest write. This is a deliberate trade-off documented in the design, not a bug.
Analysis Briefing
- Topic: Cassandra consistency levels, replication, and tunable consistency
- Analyst: Mike D (@MrComputerScience)
- Context: An adversarial analysis prompted by Claude Sonnet 4.6
- Source: Pithy Cyborg | AI News Made Simple
- Key Question: How does Cassandra let you choose your consistency guarantee per query, and what does each choice actually cost?
How Cassandra Replicates Data Across Nodes
Cassandra distributes data using consistent hashing. Each row has a partition key that hashes to a token value. Nodes own ranges of the token ring. A row belongs to the node owning its token range.
Replication factor (RF) determines how many nodes hold copies of each row. With RF=3, every row is stored on 3 nodes. The replication factor is set per keyspace. When a write arrives, the coordinator node routes it to the RF target replicas. Cassandra writes are fast because the coordinator does not wait for all replicas to acknowledge before considering the write complete.
The default behavior with consistency level ONE requires only one replica to acknowledge a write before returning success. The other replicas receive the write asynchronously. If you read at consistency level ONE immediately after writing, you may hit a replica that has not yet received the write.
Consistency Levels: What Each One Actually Means
Cassandra exposes tunable consistency at the query level. Each read and write can specify an independent consistency level.
ONE / TWO / THREE: Requires 1, 2, or 3 replicas to respond. Fast, weak consistency guarantee. Reads may return stale data if a slow replica falls behind.
QUORUM: Requires responses from a majority of replicas. With RF=3, QUORUM requires 2. A write at QUORUM and a subsequent read at QUORUM are guaranteed to overlap on at least one replica, so you always read the latest write.
LOCAL_QUORUM: Like QUORUM but constrained to the local datacenter. Used in multi-datacenter deployments to avoid cross-datacenter latency while still providing quorum guarantees locally.
ALL: Requires all RF replicas to respond. Provides the strongest consistency but is the most fragile: a single unavailable replica blocks every ALL-level read or write.
from cassandra.cluster import Cluster
from cassandra.policies import ConsistencyLevel
from cassandra.query import SimpleStatement
cluster = Cluster(['localhost'])
session = cluster.connect('your_keyspace')
# Strong consistency: read guaranteed to see latest write
strong_read = SimpleStatement(
"SELECT * FROM orders WHERE order_id = %s",
consistency_level=ConsistencyLevel.QUORUM
)
result = session.execute(strong_read, [order_id])
# Fast read: may return stale data
fast_read = SimpleStatement(
"SELECT count FROM page_views WHERE page_id = %s",
consistency_level=ConsistencyLevel.ONE
)
result = session.execute(fast_read, [page_id])
The key insight is that you choose consistency per query, not per table. An application can use QUORUM for reads that drive financial decisions and ONE for reads that power a dashboard counter.
Read Repair and Hinted Handoff: How Cassandra Self-Heals
Cassandra uses two background mechanisms to converge replicas toward consistency.
Read repair runs during reads at QUORUM or higher. When the coordinator contacts multiple replicas, it compares their responses. If replicas disagree (one has a newer version), the coordinator sends a repair write to the stale replica. This is not visible to the client but keeps replicas synchronized over time.
Hinted handoff handles temporarily unavailable replicas. If a replica is down when a write arrives, the coordinator stores a hint locally. When the replica comes back online, the coordinator replays the hint. This closes the window during which a down replica, once recovered, would serve stale reads.
nodetool repair is the manual process that runs anti-entropy repair using Merkle trees to compare and synchronize entire token ranges between replicas. For long-lived data or tables rarely read (which means read repair rarely fires), scheduling regular nodetool repair is essential for preventing replica divergence from accumulating.
What This Means For You
- Use QUORUM for reads and writes where stale data causes incorrect behavior, such as inventory counts, financial balances, or any field where two concurrent reads returning different values would create a user-visible inconsistency.
- Use ONE or LOCAL_ONE for high-volume reads where slight staleness is acceptable, such as counters, analytics dashboards, or user preference reads, because the latency and availability cost of QUORUM multiplies quickly at scale.
- Run
nodetool repairon a schedule, because Cassandra does not self-heal tables that are infrequently read, and replica divergence accumulates silently until you hit a node failure and discover your replicas have diverged by hours or days. - Set the replication factor to 3 minimum for any production keyspace, because RF=1 provides no redundancy and RF=2 makes QUORUM equivalent to ALL, eliminating the availability benefit of tunable consistency entirely.
Enjoyed this deep dive? Join my inner circle:
- Pithy Cyborg | AI News Made Simple → AI news made simple without hype.
