intermediate~2h

Cassandra — Replication Factor & Tunable Consistency

Cassandra's signature feature isn't that it replicates data — every distributed database does that. It's that you choose, on every single query, exactly how many replicas must agree before you trust the answer.

Learning objectives

  • Set a keyspace's replication factor and explain what RF actually controls.
  • Name Cassandra's standard consistency levels and compute which combinations satisfy W + R > N.
  • Choose an appropriate consistency level for a given write, and justify the choice.
  • Explain the difference between QUORUM and LOCAL_QUORUM in a multi-datacenter cluster.

Replication factor (RF) is set per keyspace — not per table, not cluster-wide — and it's simply "how many replicas of each partition should exist." A single-datacenter keyspace uses SimpleStrategy; a multi-datacenter production cluster uses NetworkTopologyStrategy, which sets RF independently per datacenter:

-- single datacenter (dev/test) CREATE KEYSPACE ecommerce WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3}; -- multi-datacenter (production): 3 replicas in each of two datacenters CREATE KEYSPACE ecommerce WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': 3, 'dc2': 3};

RF is exactly the "N" in the W + R > N quorum formula from NoSQL Foundations, Chapter 02 — the number of replicas that exist for a given partition, against which every read and write's consistency level is measured. Raising RF on an existing keyspace (ALTER KEYSPACE ... WITH replication = {...}) only changes the target — it doesn't retroactively copy existing data to the new replicas. A repair operation has to run afterward to actually stream the missing data across; skipping that step leaves new replicas silently incomplete until the next scheduled repair catches up.

💻 Code example

CREATE KEYSPACE ecommerce WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3}; CREATE KEYSPACE ecommerce WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': 3, 'dc2': 3};

NoSQL Foundations §2.1 showed that in a leaderless replication system, a write quorum of W replicas and a read quorum of R replicas are guaranteed to overlap on at least one node — and therefore guarantee the read sees the latest write — whenever W + R > N. Cassandra's consistency levels are that exact formula, exposed as two settings (one for reads, one for writes) you choose on every single query, rather than a fixed property of the cluster:

LevelReplicas that must respondNotes
ANYNone need to be a real replica yetWrites only — can be satisfied by a hinted handoff alone; weakest possible durability
ONE1Lowest latency, weakest read/write guarantee
TWO / THREE2 / 3Rarely used in practice
QUORUM⌊RF/2⌋ + 1, counted across all datacentersStrong, but a multi-DC cluster pays a cross-DC round trip
LOCAL_QUORUM⌊RF/2⌋ + 1, counted within the coordinator's own datacenterStrong within one DC, without the cross-DC latency cost
EACH_QUORUMA quorum in every datacenter, independentlyWrites only — strongest multi-DC guarantee, highest latency
ALLEvery replicaStrongest single guarantee — one slow or down replica blocks the whole request

(Cassandra also has SERIAL/LOCAL_SERIAL, reserved for its compare-and-set / lightweight-transaction feature — a separate mechanism from ordinary reads and writes, not covered here.)

With RF = 3, a QUORUM write (W = 2) plus a QUORUM read (R = 2) gives W + R = 4 > 3 — every read is guaranteed to overlap the latest write. A ONE/ONE pair gives W + R = 2, which is not greater than 3 — no such guarantee, but noticeably lower latency.

◆ Real-world example

An e-commerce platform runs a single keyspace with RF = 3, but doesn't use the same consistency level for everything in it — because not everything in it carries the same cost of being wrong.

A wallet-balance adjustment is money. It needs the strong guarantee: QUORUM on the write and QUORUM on the read, satisfying W + R > N so a read is guaranteed to see the adjustment that just landed.

A "user viewed this product" event feeding a recommendation engine is not money — occasionally losing one, or reading a slightly stale count, costs nothing anyone will notice, and the whole feed is already eventually consistent by design (NoSQL Foundations, Chapter 01's BASE model). It can use ONE, trading the consistency guarantee for lower latency and higher write throughput.

// financial adjustment — needs the quorum overlap guarantee SimpleStatement adjustBalance = SimpleStatement.builder( "UPDATE wallets SET balance = balance - ? WHERE wallet_id = ?") .addPositionalValues(amount, walletId) .setConsistencyLevel(ConsistencyLevel.QUORUM) .build(); session.execute(adjustBalance); // activity event — speed matters more than every replica agreeing immediately SimpleStatement logView = SimpleStatement.builder( "INSERT INTO product_views (product_id, user_id, viewed_at) VALUES (?, ?, ?)") .addPositionalValues(productId, userId, Instant.now()) .setConsistencyLevel(ConsistencyLevel.ONE) .build(); session.execute(logView);

Both statements run against the same keyspace, same RF, same cluster — the consistency level is a per-query decision, not a cluster-wide one. That tunability, per query, is Cassandra's signature feature relative to databases where consistency is a single global setting.

💻 Code example

SimpleStatement adjustBalance = SimpleStatement.builder( "UPDATE wallets SET balance = balance - ? WHERE wallet_id = ?") .addPositionalValues(amount, walletId) .setConsistencyLevel(ConsistencyLevel.QUORUM) .build(); session.execute(adjustBalance); SimpleStatement logView = SimpleStatement.builder( "INSERT INTO product_views (product_id, user_id, viewed_at) VALUES (?, ?, ?)") .addPositionalValues(productId, userId, Instant.now()) .setConsistencyLevel(ConsistencyLevel.ONE) .build(); session.execute(logView);

With NetworkTopologyStrategy and RF split across datacenters (say, 3 in dc1 and 3 in dc2, RF = 6 total), plain QUORUM is computed against the combined replica count across every datacenter — satisfying it can require waiting on an acknowledgment from a replica on another continent, adding real, physical round-trip latency to every request.

LOCAL_QUORUM restricts the quorum requirement to replicas in the coordinator node's own datacenter only. It gives you the same strong-overlap guarantee as QUORUM, but scoped to one datacenter, without paying a cross-DC round trip. This is why LOCAL_QUORUM (and LOCAL_ONE) are the practical default consistency levels for most multi-datacenter production Cassandra deployments — plain QUORUM/ONE are reserved for single-datacenter clusters, or for the rare case where a cross-DC-strength guarantee is genuinely required and worth its latency cost.

▲ Common mistake

Assuming QUORUM alone gives a "read-your-writes, everywhere" guarantee for free in a multi-DC cluster, without expecting the latency that comes with it. The first time p99 latency spikes because a request had to round-trip to a datacenter on another continent is a common, avoidable surprise — LOCAL_QUORUM is almost always the level actually intended.

Want a visual for this concept?

Generate a diagram tailored to “Cassandra — Replication Factor & Tunable Consistency” — the AI picks whichever visual (flowchart, comparison, sequence, etc.) best fits.

Sign in to generate a visual →

Practice quiz

Next Step

Continue to Cassandra — Why Writes Are Fast (and What Compaction Costs You)← Back to all Cassandra chapters