Tunable Consistency

TUNABLE - Master the R+W>RF Formula

⚙️ Choose the perfect consistency level for every use case! Master strong vs eventual consistency!

📖 Airbnb: When Tunable Consistency Saved the Day

Airbnb handles millions of bookings daily across 220+ countries with complex consistency requirements. The challenge: Different data types need different consistency guarantees! Problem: Using ALL for everything = 300ms+ latency (disaster for user experience). Using ONE for everything = double-bookings (disaster for business). Airbnb's solution: Tunable consistency - pick the right level for each use case! Their hybrid approach: QUORUM for bookings (can't double-book a room!), LOCAL_QUORUM for user profiles (strong local, eventual global), ONE for search cache (fast searches, eventual OK), EACH_QUORUM for billing (critical financial data). Result: Zero double-bookings, sub-20ms user experience, strong consistency where needed, performance optimized per use case. Airbnb Engineering: "Cassandra's tunable consistency lets us choose the perfect balance for each data type. You don't need to compromise - you can have both speed AND consistency in the right places!"

💻 Interactive Consistency Tuning Simulator

See how different consistency levels affect your queries! Tune consistency like a pro!

cqlsh@tuning-cluster

⚙️ Tuning Scenarios - Click to Explore:

⚙️ Consistency Tuning Simulator Ready!
🎯 Click scenarios above to see different consistency strategies
✓ Learn R+W>RF formula and how to choose the right level

⚙️ The Power of Tunable Consistency

CRITICAL: Unlike traditional databases with fixed consistency levels, Cassandra lets you tune consistency per query! You can use QUORUM for user profiles, ONE for analytics, and LOCAL_QUORUM for multi-DC deployments - all in the same cluster. This is Cassandra's superpower: you choose the perfect balance of consistency, availability, and performance for each use case!

⚙️ What is Tunable Consistency?

Imagine you're a chef with a temperature dial on your oven. You don't cook everything at the same temperature! Bread needs 180°C, pizza needs 250°C, slow-roast needs 120°C. Similarly, Cassandra's tunable consistency lets you dial the perfect "consistency temperature" for each data type!

🎯 Real-World Analogy: The Volume Knob

Your home stereo has a volume knob - you can turn it from 1 to 10. You don't play everything at volume 10!

Classical music: Volume 3 (gentle, precise)
Party playlist: Volume 7 (louder, energetic)
Background jazz: Volume 2 (barely there)

Cassandra's consistency levels work the same way:
ONE = Volume 1: Fast, eventual consistency
QUORUM = Volume 5: Balanced, strong consistency
ALL = Volume 10: Maximum guarantee, slowest

The magic? You can tune it per query! Use QUORUM for user profiles, ONE for analytics, ALL for billing - all in the same database!

⚙️

Per-Query Tuning

Behavior: Set consistency per read/write
Example: QUORUM for writes, ONE for reads
Flexibility: Different tables, different CLs
Benefit: Optimize each use case individually
Reality: Most DBs force one global setting!

🎚️

9 Consistency Levels

Options: ONE, TWO, THREE, QUORUM, ALL
Multi-DC: LOCAL_ONE, LOCAL_QUORUM, EACH_QUORUM
Special: ANY (hinted handoff)
Range: Fastest (ONE) to Strongest (ALL)
Choice: Pick what fits your needs!

⚖️

CAP Theorem Trade-off

Consistency: All nodes see same data
Availability: System always responds
Partition Tolerance: Works despite network issues
CAP says: Pick 2 of 3
Cassandra: Lets YOU choose the balance!

💡 Key Insight: You're in Control

Traditional databases force you to pick ONE consistency model for everything. PostgreSQL = always strong. MongoDB (default) = always eventual. But real applications have diverse needs! Your user profile needs strong consistency. Your analytics don't. Your cache can be stale. Cassandra's tunable consistency means you can optimize each query for exactly what it needs - no compromises!

🧮 The R+W>RF Formula: Strong Consistency Guarantee

The R+W>RF Formula: Guarantee You Read What You Write R + W > RF Read CL + Write CL > Replication Factor When this is true → Strong Consistency (always read latest write) ✅ Example 1: QUORUM + QUORUM = Strong RF = 3 (3 replicas total) Write CL = QUORUM → W = 2 (wait for 2) Read CL = QUORUM → R = 2 (query 2) R + W = 2 + 2 = 4 4 > 3 ✓ Strong Consistency! Why: Read queries 2 replicas, write updated 2 replicas → Overlap guaranteed! ❌ Example 2: ONE + ONE = Eventual RF = 3 (3 replicas total) Write CL = ONE → W = 1 (wait for 1) Read CL = ONE → R = 1 (query 1) R + W = 1 + 1 = 2 2 NOT > 3 ❌ Eventual Only! Why: Read might hit replica that wasn't updated → stale data! ✅ Example 3: QUORUM Write + ONE Read RF = 3 (3 replicas total) Write CL = QUORUM → W = 2 Read CL = ONE → R = 1 R + W = 1 + 2 = 3 3 NOT > 3 ❌ Eventual! Need R + W = 4 for strong. Use QUORUM for both! ✅ Example 4: ALL Write + ONE Read RF = 3 (3 replicas total) Write CL = ALL → W = 3 Read CL = ONE → R = 1 R + W = 1 + 3 = 4 4 > 3 ✓ Strong! (Overkill) But: ALL is slow, poor availability. QUORUM+QUORUM is better!

🧮 Formula Explained Simply

The formula R + W > RF guarantees overlap. If you write to 2 replicas and read from 2 replicas (out of 3 total), at least 1 replica MUST be in both sets! That replica has the latest data, so you're guaranteed to read what you wrote. If R + W ≤ RF, no overlap guarantee = eventual consistency = might read stale data. Most common strong setup: QUORUM + QUORUM with RF=3 → 2 + 2 = 4 > 3 ✓

📊 All 9 Consistency Levels Explained

Cassandra offers 9 different consistency levels - from fastest (ANY) to strongest (ALL). Here's the complete guide to every option!

📝

ANY (Weakest)

Behavior: Write succeeds even if NO replicas available!
Mechanism: Coordinator stores "hint" for later
Latency: ~1-2ms (instant ACK)
Consistency: Weakest possible (eventual)
Availability: Highest possible
Use case: Almost never! Maybe logging during outages
Risk: Data might be lost if coordinator fails

1️⃣

ONE (Fastest Real)

Behavior: Wait for 1 replica ACK (any DC)
Latency: 3-5ms
Throughput: 50,000 writes/sec
Consistency: Eventual (R+W=2 NOT>3)
Formula: 1 + 1 = 2 ≤ RF=3 ❌
Use case: High-volume non-critical (analytics, logs)
Multi-DC: Use LOCAL_ONE instead!

2️⃣

TWO

Behavior: Wait for 2 replica ACKs
Latency: 6-10ms
Throughput: 35,000 writes/sec
Consistency: Still eventual! (2+2=4>3 ✓ but risky)
Formula: 2 + 2 = 4 > 3 ✓ (strong if both TWO)
Use case: Rarely used, QUORUM is better
Note: Between ONE and QUORUM, not much benefit

3️⃣

THREE

Behavior: Wait for 3 replica ACKs
Latency: 20-30ms
Throughput: 15,000 writes/sec
Consistency: Strong if RF=3 (3+3>3 ✓)
Formula: 3 + 3 = 6 > 3 ✓
Use case: Rarely needed, ALL is similar
Note: QUORUM gives same guarantee, faster!

🎯

QUORUM (Recommended!)

Behavior: Wait for majority (RF=3 → 2 ACKs)
Latency: 12-18ms
Throughput: 25,000 writes/sec
Consistency: STRONG! (2+2=4>3 ✓)
Formula: ⌈RF/2⌉ + ⌈RF/2⌉ > RF ✓
Use case: 99% of production!
Sweet spot: Strong + good performance

🔴

ALL (Strongest)

Behavior: Wait for ALL replicas (RF=3 → 3 ACKs)
Latency: 40-80ms
Throughput: 8,000 writes/sec
Consistency: Strongest (all confirmed)
Availability: FAILS if ANY node down!
Use case: <1% (compliance, audit logs)
Warning: Poor availability, avoid if possible!

🌐

LOCAL_ONE

Behavior: Wait for 1 replica in LOCAL DC only
Latency: 3-5ms (guaranteed local!)
Multi-DC: Never cross-DC wait
Consistency: Eventual locally + globally
vs ONE: ONE might pick remote DC = 300ms!
Use case: High-volume non-critical in multi-DC
When: Multi-DC + need speed

🌍

LOCAL_QUORUM (Multi-DC Default!)

Behavior: QUORUM in local DC only
Latency: 8-12ms (no cross-DC wait!)
Multi-DC: 18x faster than QUORUM
Consistency: Strong locally, eventual globally
Formula: R_local + W_local > RF_local ✓
Use case: 99% of multi-DC production!
When: Always use in multi-DC!

🌏

EACH_QUORUM

Behavior: QUORUM in EACH datacenter
Latency: 250-300ms (wait for slowest DC!)
Multi-DC: Waits for US + EU + Asia
Consistency: Strong globally!
Availability: Fails if ANY DC down
Use case: <1% (critical financial, compliance)
When: Must guarantee all DCs have data

⚠️ Common Mistakes

  • ❌ Using ANY: Almost never the right choice, data loss risk
  • ❌ Using ALL everywhere: Poor availability, fails if any node down
  • ❌ Using QUORUM in multi-DC: Use LOCAL_QUORUM instead (18x faster!)
  • ❌ Using ONE in multi-DC: Might read from Asia = 300ms! Use LOCAL_ONE
  • ❌ Same CL for all tables: Tune per use case (QUORUM for users, ONE for analytics)

🎯 Consistency Level Decision Matrix

Use this decision tree to pick the perfect consistency level for your use case!

Use Case Single DC Multi-DC Why?
User Profiles
Accounts, settings, preferences
QUORUM LOCAL_QUORUM Need strong consistency, users expect immediate updates
Orders/Transactions
Purchases, reservations
QUORUM LOCAL_QUORUM Business-critical, can't double-book or lose orders
Analytics/Logs
Pageviews, events, metrics
ONE LOCAL_ONE High volume, approximate counts OK, speed matters
Session Cache
Temporary data, TTL
ONE LOCAL_ONE It's a cache! Stale = re-fetch, speed priority
Search Results
Cached queries
ONE LOCAL_ONE User experience depends on speed, stale acceptable
Billing/Payments
Financial records
ALL or QUORUM EACH_QUORUM Financial data MUST be in all DCs for compliance
Audit Logs
Compliance, regulatory
ALL EACH_QUORUM Regulatory requirement, must guarantee persistence
Comments/Reviews
User-generated content
QUORUM LOCAL_QUORUM Users expect to see their comment immediately
Inventory Counts
Stock levels
QUORUM LOCAL_QUORUM Need accuracy to prevent overselling
Counters/Stats
Like counts, view counts
ONE LOCAL_ONE Approximate counts fine, high volume

🎯 Quick Decision Tree

START: What's your deployment?
├─ Multiple datacenters?
│ ├─ Yes → Use LOCAL_* levels (never plain QUORUM!)
│ │ ├─ Need strong consistency?
│ │ │ ├─ Globally? → EACH_QUORUM (slow but global strong)
│ │ │ └─ Locally? → LOCAL_QUORUM (recommended!)
│ │ └─ Speed priority? → LOCAL_ONE (eventual)
│ └─
└─ No → Single datacenter
├─ Need strong consistency?
│ ├─ Yes → QUORUM (recommended!)
│ └─ Critical financial? → ALL (compliance)
└─ Speed priority? → ONE (eventual)

⚖️ Understanding the Trade-offs

Every consistency level is a trade-off between consistency, availability, and performance. Here's what you gain and lose with each choice!

⚡

High Performance (ONE)

✓ Gain:
• Lowest latency (3-5ms)
• Highest throughput (50k writes/sec)
• Best user experience for speed
• Works even if 2/3 nodes down

✗ Lose:
• No consistency guarantee
• 66% chance of stale reads
• Users might see old data
• Not suitable for critical data

⚖️

Balanced (QUORUM)

✓ Gain:
• Strong consistency (R+W>RF)
• Reasonable latency (12-18ms)
• Good throughput (25k writes/sec)
• Survives 1 node failure

⚠ Trade-off:
• 3-4x slower than ONE
• Moderate resource usage
• Fails if majority nodes down
• Still excellent for most cases!

🔒

High Consistency (ALL)

✓ Gain:
• Absolute certainty all nodes have data
• Compliance/audit requirements met
• No data loss risk
• Strongest guarantee possible

✗ Lose:
• Slow (40-80ms)
• Low throughput (8k writes/sec)
• FAILS if ANY node down!
• Poor availability

📊 The CAP Theorem Trade-off

The CAP Theorem states you can only pick 2 of 3:

C = Consistency (all nodes see same data)
A = Availability (system always responds)
P = Partition Tolerance (works despite network failures)

Cassandra's choice: P + A (partition tolerant + available)
→ C is tunable! You control the consistency level!

ONE: Maximum Availability, eventual Consistency
QUORUM: Balanced A + strong C
ALL: Maximum Consistency, poor Availability

This is the power of tunable consistency: You slide the dial between C and A based on your needs!

🏢 How Real Companies Tune Consistency

🛒 Airbnb: Hybrid Consistency Strategy

Scale: 7M+ listings, 220+ countries, multi-DC deployment
Challenge: Different data types need different consistency guarantees

✓ Bookings Table (LOCAL_QUORUM):
• Can't double-book a room - need strong consistency
• Multi-DC deployment requires LOCAL_QUORUM
• Latency: 10-15ms (acceptable for booking flow)
• Formula: R + W = 2 + 2 = 4 > 3 ✓ Strong locally

⚡ Search Cache (LOCAL_ONE):
• Millions of searches per minute
• Stale results acceptable (they re-fetch if needed)
• Latency: 3-5ms (instant search results)
• Throughput: 100k+ reads/sec

📊 User Profiles (LOCAL_QUORUM):
• Users expect to see their profile changes immediately
• Latency: 8-12ms (good UX)
• Strong consistency within region

💰 Billing (EACH_QUORUM):
• Financial transactions MUST be in all datacenters
• Latency: 250ms (slow but acceptable for payments)
• Compliance requirement: all DCs must have record

Result: Zero double-bookings, instant search, strong consistency where needed!

📱 Instagram: Tuning for Billions of Interactions

Scale: 2B+ users, 95M+ photos/videos per day
Strategy: Different consistency per feature

Posts/Comments (LOCAL_QUORUM):
• Users expect to see their posts immediately
• "Where's my post?" = bad UX
• Latency: 10-15ms for posting
• Strong consistency within DC

Like Counts (LOCAL_ONE):
• Approximate counts are fine
• Huge volume: billions of likes per day
• Latency: 2-3ms per like
• "12.3k likes" vs "12.4k likes" doesn't matter

Feed Timeline (LOCAL_ONE):
• Users scroll fast, eventual consistency OK
• Missing a post briefly is acceptable
• Latency: 3-5ms to load feed
• Refresh shows updated feed

Instagram Engineering: "We tune consistency per table. Posts need strong consistency. Counters and feeds can be eventual. This lets us handle billions of interactions per day with great user experience!"

💳 Stripe: Financial Data Requires EACH_QUORUM

Scale: Processes billions in payments annually, global infrastructure
Requirement: Financial data MUST be in all datacenters

Payment Transactions (EACH_QUORUM):
• Regulatory requirement: all DCs must have record
• Cannot lose financial data under ANY circumstance
• Latency: 200-300ms (acceptable for payments)
• Strong consistency globally guaranteed
• Worth the latency cost for compliance

Customer Profiles (LOCAL_QUORUM):
• Need strong consistency for account data
• But don't need all DCs for every profile update
• Latency: 10-15ms (good UX)

API Request Logs (LOCAL_ONE):
• High volume: millions of API calls per minute
• Logs are for analytics, eventual OK
• Latency: 2-3ms per log write

Trade-off: EACH_QUORUM is slow (300ms) but necessary for financial compliance. Most payments systems use it for transaction records.

✅ Best Practices for Tunable Consistency

1️⃣

1. Start with QUORUM, Optimize Later

Rule: Default to QUORUM (or LOCAL_QUORUM in multi-DC)
Why: Strong consistency + good performance
Optimize: Profile your workload first
Then: Drop to ONE for proven high-volume non-critical
Never: Start with ONE and wonder why data is inconsistent!
Pattern: Strong first, relax when safe

2️⃣

2. Use Hybrid Strategy Per Table

Don't: Use same CL for all tables!
Do: Tune per table based on needs
Users table: QUORUM (critical data)
Analytics table: ONE (high-volume)
Billing table: ALL or EACH_QUORUM
Benefit: Optimize each use case individually

3️⃣

3. Always Use LOCAL_* in Multi-DC

If multi-DC: ALWAYS use LOCAL_ prefix!
Never: Use QUORUM in multi-DC (150-300ms!)
Use: LOCAL_QUORUM instead (8-12ms)
Exception: EACH_QUORUM for critical global
Performance: 18-35x faster!
Remember: ONE → LOCAL_ONE, QUORUM → LOCAL_QUORUM

4️⃣

4. Match Read/Write Consistency

For strong: Use same CL for reads + writes
Example: Write QUORUM + Read QUORUM
Formula: R + W > RF guarantees strong
Mistake: Write QUORUM + Read ONE = eventual!
Optimization: Write QUORUM + Read ONE OK if eventual acceptable
Test: Verify R + W > RF for your setup

5️⃣

5. Test Failure Scenarios

Test 1: Kill 1 node, verify QUORUM still works
Test 2: Kill 2 nodes, verify writes fail gracefully
Test 3: Multi-DC: kill entire DC, verify behavior
Test 4: Network partition between nodes
Tool: Chaos engineering (Chaos Monkey)
Goal: Understand your availability guarantees

6️⃣

6. Monitor Consistency Metrics

Track: Read/write latency per CL
Alert: High read repair rate (stale reads)
Monitor: Failed writes (insufficient replicas)
Check: Hinted handoff queue size
Tool: Grafana + Prometheus dashboards
Goal: Detect consistency issues early

7️⃣

7. Document Your Consistency Choices

For each table: Document why you chose that CL
Example: "users: QUORUM because profile updates must be immediate"
Include: Formula verification (R+W>RF?)
Review: Quarterly consistency strategy review
Share: Team knowledge about trade-offs
Prevent: "Why is this table using ONE?"

8️⃣

8. Avoid Common Anti-Patterns

❌ Don't: Use ANY (almost never right)
❌ Don't: Use ALL everywhere (poor availability)
❌ Don't: Mix RF and CL incorrectly
❌ Don't: Use QUORUM in multi-DC
❌ Don't: Assume ONE is "always fine"
✓ Do: Think through each use case carefully

9️⃣

9. Performance Test Before Production

Benchmark: Test each CL with production load
Measure: P50, P99, P999 latencies
Compare: QUORUM vs ONE for your workload
Validate: R+W>RF gives strong consistency
Tool: cassandra-stress, custom load tests
Goal: Know your performance characteristics

⚠️ Critical Mistakes to Avoid

  • ❌ Using ONE for user-facing critical data: Users will see inconsistent state!
  • ❌ Not verifying R+W>RF: You think you have strong consistency but don't
  • ❌ Using QUORUM in multi-DC: 150-300ms latency kills user experience
  • ❌ Same CL for all tables: Missing huge optimization opportunities
  • ❌ Not testing node failures: Surprises in production when nodes fail
  • ❌ Using ALL without understanding availability impact: One node down = entire write path down!

🎯 Production Recommendation

Single Datacenter:
• Default: QUORUM for reads + writes (strong consistency)
• High-volume non-critical: ONE (analytics, logs, caches)
• Critical financial: ALL (compliance, audit logs)

Multi-Datacenter:
• Default: LOCAL_QUORUM for reads + writes (strong local, fast)
• High-volume non-critical: LOCAL_ONE (analytics, logs)
• Global critical: EACH_QUORUM (billing, compliance)

The Golden Rule: Start with strong consistency (QUORUM/LOCAL_QUORUM), then optimize specific tables to ONE/LOCAL_ONE when profiling shows they're safe and would benefit from the performance boost!

💼 Interview Questions & Answers

1
Explain the R+W>RF formula and prove how QUORUM provides strong consistency with RF=3.

Complete Answer:

The R+W>RF formula is the mathematical guarantee for strong consistency in Cassandra. It ensures that reads and writes overlap, guaranteeing you always read the most recent write.

The Formula:

  • R = Read consistency level (number of replicas queried)
  • W = Write consistency level (number of replicas that must acknowledge)
  • RF = Replication Factor (total number of replicas)
  • If R + W > RF → Strong Consistency Guaranteed!

Why This Works - The Overlap Principle:

Imagine RF=3 (3 total replicas: A, B, C):

  • Write with W=2 means 2 replicas must acknowledge (e.g., A and B got the write)
  • Read with R=2 means we query 2 replicas (e.g., B and C)
  • Notice: Replica B is in BOTH sets! → Guaranteed overlap!
  • Since B has the latest data, our read will return the latest value

Proof with QUORUM (RF=3):

  • QUORUM = majority = ⌈3/2⌉ = 2 replicas
  • Write CL = QUORUM → W = 2
  • Read CL = QUORUM → R = 2
  • R + W = 2 + 2 = 4
  • 4 > 3 (RF) ✓ Strong Consistency!

Step-by-Step Timeline:

  • T=0: Write "name=Alice" with CL=QUORUM
    • Coordinator sends to replicas A, B, C
    • Replicas A, B acknowledge → QUORUM satisfied (2 of 3)
    • Write returns SUCCESS (C might still have old value)
  • T=10ms: Read with CL=QUORUM
    • Coordinator queries 2 replicas (any 2 of A, B, C)
    • Possible combinations: (A,B), (A,C), or (B,C)
    • ALL combinations include at least one updated replica!
    • (A,B) → both have new value ✓
    • (A,C) → A has new value ✓
    • (B,C) → B has new value ✓
    • Coordinator returns newest value → "Alice" ✓

Counter-Example - ONE + ONE (Eventual):

  • Write CL = ONE → W = 1
  • Read CL = ONE → R = 1
  • R + W = 1 + 1 = 2
  • 2 NOT > 3 ❌ Eventual Only!
  • Why fails: Write updates only A, read might query C (stale!)
  • No guaranteed overlap → might read stale data

General Formula for Any RF:

  • For strong consistency: R + W > RF
  • RF=3: R=2, W=2 → 4 > 3 ✓ (QUORUM)
  • RF=5: R=3, W=3 → 6 > 5 ✓ (QUORUM)
  • RF=7: R=4, W=4 → 8 > 7 ✓ (QUORUM)
  • Pattern: QUORUM + QUORUM always gives strong consistency!

Key Insight: The formula R+W>RF guarantees overlap because the sum of replicas accessed (R+W) exceeds the total available (RF), making it mathematically impossible to miss the latest write. This is the foundation of tunable consistency - you can choose different R and W values to trade between consistency strength and performance!

2
When would you choose QUORUM vs ALL vs ONE? Walk through the decision process for a real application.

Complete Answer:

The choice between QUORUM, ALL, and ONE depends on your specific requirements for consistency, availability, and performance. Let me walk through a real e-commerce application example.

Application: E-commerce Platform

Setup: Single datacenter, RF=3, multiple data types with different requirements

Use Case 1: User Profiles → QUORUM ✓

Decision Process:

  • Consistency need: HIGH - users expect to see profile changes immediately
  • Performance need: MODERATE - 12-18ms acceptable for profile updates
  • Availability need: HIGH - must work even if 1 node down
  • Why QUORUM:
    • Strong consistency (R+W>RF: 2+2=4>3 ✓)
    • Reasonable latency (12ms vs 40ms for ALL)
    • Good availability (works if 1/3 nodes down)
    • User updates email → sees new email immediately ✓
  • Why not ALL: Slower (40ms), fails if ANY node down
  • Why not ONE: User might see old email (confusing UX)

Use Case 2: Product Analytics → ONE ✓

Decision Process:

  • Consistency need: LOW - approximate counts are fine
  • Performance need: VERY HIGH - millions of pageviews per minute
  • Availability need: VERY HIGH - never block analytics writes
  • Why ONE:
    • Fastest (3ms vs 12ms for QUORUM = 4x faster)
    • Highest throughput (50k vs 25k writes/sec = 2x more)
    • Works even if 2/3 nodes down
    • "12,347 views" vs "12,351 views" doesn't matter
  • Why not QUORUM: 4x slower, half the throughput (unnecessary for analytics)
  • Why not ALL: Way too slow for high-volume analytics

Use Case 3: Purchase Orders → QUORUM ✓

Decision Process:

  • Consistency need: VERY HIGH - can't lose orders!
  • Performance need: MODERATE - 15ms acceptable during checkout
  • Availability need: HIGH - must process orders with 1 node down
  • Why QUORUM:
    • Strong consistency (order confirmed = definitely saved)
    • Acceptable latency for checkout flow
    • Survives 1 node failure (good availability)
  • Why not ALL: One node failure = can't process orders (unacceptable!)
  • Why not ONE: Risk of lost orders if that one node crashes before replication

Use Case 4: Billing Transactions → ALL ✓

Decision Process:

  • Consistency need: ABSOLUTE - financial compliance requirement
  • Performance need: LOW - 50ms acceptable for billing
  • Availability need: MODERATE - billing can wait briefly if node down
  • Why ALL:
    • Regulatory requirement: ALL replicas must have financial records
    • Audit trail: can prove data is on all nodes
    • Cannot risk losing billing data under ANY circumstance
    • Slower, but billing is low-volume (100s not millions)
  • Why not QUORUM: Compliance needs all-replicas confirmation
  • Why not ONE: Completely unacceptable for financial data
  • Trade-off: Worth the availability cost for financial data

Use Case 5: Session Cache → ONE ✓

Decision Process:

  • Consistency need: NONE - it's a cache! Stale = re-fetch
  • Performance need: VERY HIGH - must be instant
  • Availability need: VERY HIGH - never block user sessions
  • Why ONE:
    • Fastest possible (3ms)
    • Cache invalidation on stale reads is fine
    • High availability (works with 2/3 nodes down)

Decision Framework Summary:

Consistency Need Performance Need Recommended CL
Absolute (Financial) Can be slow ALL
High (User-facing) Moderate OK QUORUM
Low (Analytics) Must be fast ONE
None (Cache) Must be instant ONE

Key Lesson: Don't use the same consistency level for everything! Profile your application, understand your requirements, and choose appropriately. QUORUM is the sweet spot for most use cases, ONE for high-volume non-critical, and ALL only when absolutely required for compliance.

3
A team reports users seeing "ghost data" - updates disappearing then reappearing. What consistency issue is this and how do you fix it?

Complete Answer:

This is a classic symptom of using ONE for both reads and writes without proper understanding of eventual consistency. Let me diagnose and fix this.

The Problem - "Ghost Data" Timeline:

  • T=0: User updates email to "alice@newdomain.com"
    • Write CL=ONE → Only Replica A gets updated (3ms)
    • Replicas B, C still have old email "alice@olddomain.com"
    • Client gets SUCCESS ✓
  • T=5ms: User refreshes page immediately
    • Read CL=ONE → Coordinator picks Replica B (random)
    • Replica B has OLD email!
    • User sees "alice@olddomain.com" ❌ (confused!)
  • T=10ms: User refreshes again
    • This time coordinator picks Replica A
    • User sees "alice@newdomain.com" ✓
  • T=15ms: User refreshes once more
    • Coordinator picks Replica C
    • User sees "alice@olddomain.com" again! ❌
    • "Ghost data" - update disappeared!
  • T=50ms: Background replication completes
    • All replicas now consistent
    • User finally sees new email consistently ✓

Root Cause Analysis:

  • Formula check: R + W = 1 + 1 = 2 ≤ RF=3 ❌
  • Problem: No guarantee of overlap!
  • Write: Only 1/3 replicas updated immediately
  • Read: Might query any of the 3 replicas
  • Probability: 66% chance (2/3) of reading stale data!
  • Duration: 20-50ms until replication completes

Solution 1: Use QUORUM (Recommended)

-- Change consistency to QUORUM ALTER TABLE users WITH default_read_consistency_level = 'QUORUM' AND default_write_consistency_level = 'QUORUM'; -- Or use per-query CL INSERT INTO users (...) USING CONSISTENCY QUORUM; SELECT * FROM users WHERE ... USING CONSISTENCY QUORUM;

Why this works:

  • Write QUORUM → 2/3 replicas updated (12ms)
  • Read QUORUM → Query 2/3 replicas
  • R + W = 2 + 2 = 4 > 3 ✓ Guaranteed overlap!
  • Always read at least one updated replica
  • No more ghost data! ✓

Solution 2: SERIAL CONSISTENCY (If needed)

-- For critical updates that must be linearizable UPDATE users SET email='alice@newdomain.com' WHERE id=123 IF email='alice@olddomain.com' -- Lightweight transaction USING CONSISTENCY QUORUM;

When to use: Critical updates that need compare-and-swap atomicity

Solution 3: Read Repair (Automatic)

  • Cassandra has built-in read repair
  • When coordinator sees different values, it updates stale replicas
  • Helps eventual consistency converge faster
  • But: Doesn't prevent initial ghost data!
  • Still need proper CL for strong consistency

Monitoring & Detection:

-- Check read repair activity (high = lots of stale reads) nodetool tablestats keyspace.users | grep "Read Repair" -- Monitor hint activity nodetool tpstats | grep "HintedHandoff" -- Check for consistency issues in logs grep "Digest mismatch" /var/log/cassandra/system.log

Performance Impact Comparison:

Metric ONE + ONE (Broken) QUORUM + QUORUM (Fixed)
Write Latency 3ms ⚡ 12ms
Ghost Data 66% probability ❌ 0% ✓
User Experience Confusing ❌ Consistent ✓
Production Ready No ❌ Yes ✓

Real Production Story:

A social media company had this exact issue. Users would post a comment, see it appear, then refresh and it was gone! They were using ONE/ONE for "performance." After switching to QUORUM/QUORUM, ghost data disappeared entirely. Yes, writes went from 3ms to 12ms, but 12ms is still instant to users, and the UX improvement was massive. Users stopped reporting bugs!

Key Takeaway: Ghost data = eventual consistency showing its ugly side. For user-facing data, ALWAYS use QUORUM to guarantee R+W>RF. The 4x performance "benefit" of ONE is not worth confusing your users with inconsistent data!

4
You have a multi-DC deployment. Explain why using QUORUM is wrong and what you should use instead.

Complete Answer:

Using plain QUORUM in multi-datacenter deployments is one of the most common and expensive mistakes in Cassandra. Let me explain why it's wrong and the correct approach.

Setup: Multi-DC Deployment

  • 3 datacenters: US East, Europe, Asia
  • RF = 3 per datacenter
  • Total replicas globally = 9 (3×3)
  • User makes request from US East

The Problem with QUORUM in Multi-DC:

What QUORUM Means:

  • QUORUM = majority of ALL replicas globally
  • Total RF = 9 → QUORUM = 5 replicas
  • Coordinator must wait for 5 ACKs from ANY datacenters
  • This is where it goes wrong!

Disaster Timeline with QUORUM:

  • T=0: US client writes with CL=QUORUM
    • Coordinator in US sends to all 9 replicas
    • Must wait for 5 ACKs (majority)
  • T=8ms: US replicas respond (3 ACKs) - Not enough!
    • Need 2 more ACKs...
    • Must wait for cross-DC responses
  • T=150ms: Europe replicas respond (+3 ACKs = 6 total)
    • QUORUM satisfied! (6 > 5)
    • Client finally gets SUCCESS
    • User waited 150ms! ❌

Performance Disaster:

Metric QUORUM (Wrong) LOCAL_QUORUM (Correct)
Write Latency 150-300ms ❌ 8-12ms ✓
Throughput 2,000/sec ❌ 30,000/sec ✓
Performance 18x slower! ❌ Baseline ✓
User Experience Terrible ❌ Excellent ✓

The Correct Solution: LOCAL_QUORUM

What LOCAL_QUORUM Means:

  • QUORUM of replicas in LOCAL datacenter only
  • US client → needs QUORUM of US replicas only
  • RF_local = 3 → QUORUM_local = 2
  • Wait for 2 US replicas, ignore EU/Asia!

Success Timeline with LOCAL_QUORUM:

  • T=0: US client writes with CL=LOCAL_QUORUM
    • Coordinator sends to all 9 replicas globally
    • BUT only waits for 2 US replicas!
  • T=5ms: US Replica 1 ACKs ✓
  • T=8ms: US Replica 2 ACKs ✓
    • LOCAL_QUORUM satisfied!
    • Client gets SUCCESS at 8ms! ⚡
  • T=150ms: EU replicas get data (background)
    • Client already moved on!
    • Async cross-DC replication
  • T=280ms: Asia replicas get data (background)
    • Eventually consistent globally

Consistency Guarantees:

  • Local DC: Strong consistency!
    • R_local + W_local = 2 + 2 = 4 > 3 ✓
    • US users always see latest US writes
  • Cross-DC: Eventual consistency
    • EU users see US writes within ~150ms
    • Acceptable for most use cases!

Complete Multi-DC Strategy:

1. Use LOCAL_QUORUM (99% of cases):

-- User profiles, orders, most data CREATE TABLE users (...); INSERT INTO users (...) USING CONSISTENCY LOCAL_QUORUM; SELECT * FROM users WHERE ... USING CONSISTENCY LOCAL_QUORUM;

2. Use LOCAL_ONE (High-volume non-critical):

-- Analytics, logs, metrics CREATE TABLE pageviews (...); INSERT INTO pageviews (...) USING CONSISTENCY LOCAL_ONE;

3. Use EACH_QUORUM (Critical cross-DC):

-- Financial transactions, compliance CREATE TABLE billing (...); INSERT INTO billing (...) USING CONSISTENCY EACH_QUORUM; -- Read can still use LOCAL_QUORUM (fast) SELECT * FROM billing WHERE ... USING CONSISTENCY LOCAL_QUORUM;

Why Companies Get This Wrong:

  • Misconception: "QUORUM = strong consistency everywhere"
  • Reality: QUORUM in multi-DC = slow + still not global strong!
  • Correct thinking: LOCAL_QUORUM = strong locally + fast
  • For global strong: Use EACH_QUORUM (explicitly)

Real Production Mistake:

A fintech company migrated from single-DC to multi-DC. They kept using QUORUM everywhere. Result: Latency jumped from 12ms to 200ms overnight! Users complained about slow app. After switching to LOCAL_QUORUM, latency dropped back to 12ms. User satisfaction recovered. The fix was literally changing one word in their consistency level!

Decision Tree for Multi-DC:

Q: Do you have multiple datacenters?
└─ Yes →
├─ Need global strong consistency?
│ └─ Yes → EACH_QUORUM (slow but global strong)
│ └─ No → Continue...
├─ Need strong consistency locally?
│ └─ Yes → LOCAL_QUORUM (recommended!)
│ └─ No → LOCAL_ONE (speed priority)
└─ NEVER: Use plain QUORUM/ONE in multi-DC!

Key Takeaway: In multi-DC deployments, ALWAYS use LOCAL_* consistency levels. Plain QUORUM forces cross-DC coordination that kills performance without providing global consistency guarantees. LOCAL_QUORUM gives you strong local consistency at 8-12ms, while QUORUM gives you eventual global consistency at 150-300ms - the worst of both worlds!

5
Design a consistency strategy for a global social media platform. Justify each choice.

Complete Answer:

Let me design a comprehensive consistency strategy for a global social media platform similar to Instagram/Twitter, with detailed justification for each decision.

Platform Requirements:

  • 2B+ users globally
  • 500M+ posts per day
  • Billions of likes/comments daily
  • Multi-datacenter deployment (US, EU, Asia, South America)
  • RF = 3 per datacenter
  • Sub-20ms user experience target

Table 1: Users (Profiles & Account Data)

Consistency Level: LOCAL_QUORUM

CREATE TABLE users ( user_id bigint PRIMARY KEY, username text, email text, password_hash text, bio text, profile_pic_url text ); -- Writes: LOCAL_QUORUM -- Reads: LOCAL_QUORUM

Justification:

  • Why LOCAL_QUORUM:
    • Users expect profile changes immediately
    • "I just updated my bio, why don't I see it?" = bad UX
    • Strong consistency within region prevents ghost data
    • Multi-DC: LOCAL avoids 150-300ms cross-DC latency
  • Performance: 10-15ms profile updates (acceptable)
  • Throughput: 25k updates/sec per DC (sufficient)
  • Cross-DC: Eventual (150ms) is fine - EU user viewing US profile can wait briefly
  • Formula: R + W = 2 + 2 = 4 > 3 ✓ Strong locally

Table 2: Posts (Content)

Consistency Level: LOCAL_QUORUM

CREATE TABLE posts ( post_id uuid PRIMARY KEY, user_id bigint, content text, image_urls list<text>, created_at timestamp ); -- Writes: LOCAL_QUORUM -- Reads: LOCAL_QUORUM

Justification:

  • Why LOCAL_QUORUM:
    • User posts and immediately checks their profile → must see it!
    • Strong local consistency prevents "where's my post?" confusion
    • Worth 10-15ms for good UX
  • Volume: 500M posts/day = 6k/sec globally → ~1.5k/sec per DC (manageable with LOCAL_QUORUM)
  • Cross-DC: Eventual is OK - if EU user views US post 150ms after posting, acceptable

Table 3: Likes (High-Volume Interactions)

Consistency Level: LOCAL_ONE

CREATE TABLE post_likes ( post_id uuid, user_id bigint, liked_at timestamp, PRIMARY KEY (post_id, user_id) ); -- Writes: LOCAL_ONE -- Reads: LOCAL_ONE (aggregate counts)

Justification:

  • Why LOCAL_ONE:
    • HUGE volume: Billions of likes per day!
    • Approximate counts acceptable: "12.3k likes" vs "12.4k likes" doesn't matter
    • Speed critical: Like button must feel instant (2-3ms)
    • Eventual consistency fine for social engagement metrics
  • Performance: 3-5ms per like, 50k+ likes/sec per DC
  • Trade-off: Like count might be slightly off for a few seconds - acceptable!
  • User expectation: Nobody expects exact real-time like counts

Table 4: Comments (User-Generated Content)

Consistency Level: LOCAL_QUORUM

CREATE TABLE comments ( post_id uuid, comment_id uuid, user_id bigint, content text, created_at timestamp, PRIMARY KEY (post_id, created_at, comment_id) ); -- Writes: LOCAL_QUORUM -- Reads: LOCAL_QUORUM

Justification:

  • Why LOCAL_QUORUM:
    • User posts comment and immediately refreshes → must see it!
    • "Where's my comment?" = bad UX (ghost data problem)
    • Comments are content, need strong consistency
  • Volume: Lower than likes (maybe 100M comments/day globally)
  • Latency: 10-15ms acceptable for commenting flow

Table 5: User Timeline/Feed (Personalized Feed)

Consistency Level: LOCAL_ONE

CREATE TABLE user_timeline ( user_id bigint, post_id uuid, posted_at timestamp, PRIMARY KEY (user_id, posted_at, post_id) ); -- Writes: LOCAL_ONE (feed updates) -- Reads: LOCAL_ONE (loading feed)

Justification:

  • Why LOCAL_ONE:
    • Users scroll feeds rapidly, eventual is fine
    • Missing a post briefly → appears on next refresh
    • Speed critical: Must load feed in 3-5ms
    • HUGE read volume: millions of timeline loads/sec
  • User behavior: Nobody expects perfect real-time feed
  • Refresh pattern: Users refresh frequently anyway

Table 6: Follower Relationships

Consistency Level: LOCAL_QUORUM

CREATE TABLE followers ( user_id bigint, follower_id bigint, followed_at timestamp, PRIMARY KEY (user_id, follower_id) ); -- Writes: LOCAL_QUORUM -- Reads: LOCAL_QUORUM

Justification:

  • Why LOCAL_QUORUM:
    • User follows someone → checks following list → must see it!
    • Inconsistent follow/unfollow state confusing
    • Moderate volume (not as high as likes)

Table 7: Direct Messages (Private Communication)

Consistency Level: EACH_QUORUM (writes), LOCAL_QUORUM (reads)

CREATE TABLE messages ( conversation_id uuid, message_id uuid, sender_id bigint, content text, sent_at timestamp, PRIMARY KEY (conversation_id, sent_at, message_id) ); -- Writes: EACH_QUORUM (critical!) -- Reads: LOCAL_QUORUM (fast)

Justification:

  • Why EACH_QUORUM for writes:
    • Privacy/legal requirement: Messages MUST be in all DCs
    • Can't lose private messages under ANY circumstance
    • Worth 250-300ms latency for message sending
    • Compliance: Law enforcement requests need complete data
  • Why LOCAL_QUORUM for reads:
    • Reading can be fast (8-12ms)
    • By read time, EACH_QUORUM write already propagated

Table 8: Analytics Events (Internal)

Consistency Level: LOCAL_ONE

CREATE TABLE analytics_events ( event_id uuid PRIMARY KEY, user_id bigint, event_type text, event_data map<text, text>, timestamp timestamp ); -- Writes: LOCAL_ONE -- Reads: Rarely (batch processing)

Justification:

  • Why LOCAL_ONE:
    • Massive volume: billions of events per day
    • Internal analytics, approximate counts fine
    • Must not impact user-facing performance
    • 2-3ms writes, 100k+ events/sec

Summary Strategy Table:

Table Write CL Read CL Why
Users LOCAL_QUORUM LOCAL_QUORUM Strong local for profile updates
Posts LOCAL_QUORUM LOCAL_QUORUM User must see their post
Likes LOCAL_ONE LOCAL_ONE Huge volume, approximate OK
Comments LOCAL_QUORUM LOCAL_QUORUM User must see their comment
Timeline LOCAL_ONE LOCAL_ONE Speed priority, eventual OK
Followers LOCAL_QUORUM LOCAL_QUORUM Prevent ghost follow/unfollow
Messages EACH_QUORUM LOCAL_QUORUM Privacy/legal requirement
Analytics LOCAL_ONE LOCAL_ONE Max throughput, approx OK

Overall Architecture Principles:

  • Default to LOCAL_QUORUM: Strong local consistency for user-facing data
  • Optimize to LOCAL_ONE: High-volume metrics and analytics
  • Use EACH_QUORUM sparingly: Only for compliance/legal requirements
  • Never use plain QUORUM: In multi-DC, always use LOCAL_ prefix!
  • Performance target: 95% of operations under 20ms

Key Insight: Don't use one-size-fits-all! A global social media platform has diverse consistency needs. Profile updates need strong consistency (LOCAL_QUORUM), likes need speed (LOCAL_ONE), and private messages need global guarantees (EACH_QUORUM). Tuning per table based on actual requirements is what makes Cassandra powerful!

Advertisement

Responsive Ad