Caching Strategies in Cassandra
Give Cassandra a memory boost! Caching keeps popular data ready in RAM, so queries donโt have to search storage every time โ like keeping your favorite snacks within armโs reach.
๐ The Story: Lisa's 100ms to 2ms Journey
Lisa's e-commerce platform served 10 million users. Product pages loaded in 100ms - acceptable but not great. Her manager wanted sub-10ms response times. Here's how caching made it possible...
๐ The Problem: Everything from Disk
Lisa's Initial Setup:
- ๐ Read Pattern: Product catalog (1M products, heavily read)
- โก Query Latency: 100ms per product page
- ๐พ Caching: None - every read hits disk!
- ๐ฅ Disk I/O: 80% utilization (bottleneck!)
- ๐ก User Experience: Pages felt sluggish
What Was Happening:
- Every Query: Read from 5-10 SSTables on disk
- Bloom Filter Check: 0.5ms (in memory - fast)
- Partition Index Lookup: 5ms (disk read - slow!)
- Data Block Read: 10-20ms per SSTable
- Multiple SSTables: 5-10 SSTables ร 15ms = 75-150ms!
- Total: 100ms average, 200ms P99
๐ The Solution: Three-Layer Caching!
Lisa's Optimized Setup:
Layer 1: Row Cache (Hot Products)
โ Result: Hot products served from RAM - 0.5ms latency!
Layer 2: Key Cache (Always On)
โ Result: Skip partition index reads - saves 5-10ms!
Layer 3: OS Page Cache (Automatic)
โ Result: Frequently accessed SSTables cached - 2-5ms!
The Results:
- โก Hot Products: 100ms โ 0.5ms (200x faster!)
- โก Warm Products: 100ms โ 2-5ms (20-50x faster!)
- โก Cold Products: 100ms โ 10-20ms (still 5-10x faster!)
- ๐ Cache Hit Rate: 95% (excellent!)
- ๐พ Disk I/O: 80% โ 20% (freed up disk!)
- ๐ User Experience: Pages feel instant!
Lisa learned: Caching = 100x performance improvement for free! ๐
๐พ Caching Fundamentals
Understand how Cassandra's multi-layer caching works!
๐ฏ Why Caching Matters
Cassandra's read path involves multiple disk I/O operations. Each SSTable read takes 5-20ms on SSD. Caching stores frequently accessed data in RAM (0.1ms access time), making reads 100-200x faster!
The Read Path Without Caching
Cassandra's Three Cache Layers
Row Cache
- What: Entire rows in memory
- Speed: 0.1-0.5ms (fastest!)
- Use Case: Hot data (top 10%)
- Size: 1-5GB typical
- Hit Rate: 90%+ for hot data
Key Cache
- What: Partition key locations
- Speed: 1-2ms (fast!)
- Use Case: Skip index lookup
- Size: 100MB-1GB typical
- Hit Rate: 95%+ always on
OS Page Cache
- What: SSTables in OS memory
- Speed: 2-5ms (good!)
- Use Case: Warm data
- Size: All remaining RAM
- Hit Rate: 60-80% for warm
๐ฅ Row Cache (Layer 1)
The fastest cache - stores entire rows in memory!
โก How Row Cache Works
Row cache stores complete partition data in off-heap memory. When a row is cached, Cassandra can return it in 0.1-0.5ms without touching SSTables at all. It's 100-200x faster than disk!
Enabling Row Cache
Row Cache Configuration
When to Use Row Cache
Perfect For
- Hot Data: Top 10% most accessed
- Small Rows: < 1KB per row
- Read-Heavy: 95%+ reads
- Predictable Access: Same data repeatedly
- Low Cardinality: Few distinct keys
Examples: User sessions, product catalog
Avoid For
- Large Rows: > 10KB per row
- Write-Heavy: Frequent updates
- High Cardinality: Millions of unique keys
- Random Access: No clear hot data
- Memory Limited: < 16GB RAM
Examples: Time-series, logs, analytics
Row Cache Performance Impact
Cache Hit (Fast Path)
Cache Miss (Slow Path)
Row Cache Gotchas
- โ ๏ธ Invalidation on Write: Any update invalidates entire partition from cache
- โ ๏ธ Cold Start: Cache empty after restart (unless saved)
- โ ๏ธ Memory Pressure: Can cause GC issues if too large
- โ ๏ธ Not for TTL Data: Cached even after expiration (until invalidated)
Monitoring Row Cache
๐ Key Cache (Layer 2)
Always-on cache that skips partition index lookups!
๐ฏ What Key Cache Does
Key cache stores the location of partition keys within SSTables. Without it, Cassandra must read the partition index from disk (5-10ms). With key cache, this lookup happens in memory (< 1ms). It's enabled by default and you should almost never disable it!
Key Cache vs No Key Cache
Without Key Cache
- Bloom filter check (0.5ms)
- Read partition index from disk (5-10ms ๐)
- Read data block from disk (10ms ๐)
- Total: 15-20ms per SSTable
With Key Cache (Default)
- Bloom filter check (0.5ms)
- Key cache lookup in memory (0.5ms โก)
- Read data block from disk (10ms ๐)
- Total: 11ms per SSTable
Saves 5-10ms per SSTable = 50-100ms for 10 SSTables!
Key Cache Configuration
Sizing Key Cache
Key Cache Size Formula
Each cached key entry is approximately 200 bytes
Monitoring Key Cache
Key Cache Best Practices
- โ Always Keep Enabled: It's always beneficial
- โ Size Appropriately: Should cache all partition keys if possible
- โ Monitor Hit Rate: Target > 95%
- โ Save Period: Enable save_period to survive restarts
๐พ OS Page Cache (Layer 3)
The automatic cache that uses remaining system RAM!
๐ฏ How OS Page Cache Works
The operating system automatically caches file contents in unused RAM. When Cassandra reads an SSTable from disk, the OS caches those blocks. Next read? Served from RAM at 2-5ms instead of 10-20ms from disk. It's completely automatic and uses all RAM not allocated to JVM/caches!
Memory Allocation Strategy
OS Page Cache Benefits
Advantages
- Automatic: Zero configuration needed
- Large: Uses all free RAM (45GB+)
- No GC: Doesn't affect JVM
- Smart: OS manages LRU automatically
- Universal: Works for all tables
How to Optimize
- More RAM: More cache space
- Small JVM Heap: 8-16GB leaves more for OS
- Compression: More data fits in cache
- Fewer SSTables: Better cache utilization
- Hot Paths: Frequently read data stays cached
Monitoring OS Page Cache
OS Cache Effectiveness
Rule of Thumb:
- If working set < OS cache size โ 90%+ cache hit rate
- If working set > OS cache size โ Cache hit rate drops
- Example: 100GB SSTables, 45GB OS cache โ Top 45GB cached (hot data)
๐ฏ Caching Strategy Guide
Choose the right caching configuration for your workload!
Decision Matrix
| Workload Type | Row Cache | Key Cache | OS Cache |
|---|---|---|---|
| Read-Heavy, Hot Data | โ 2-5GB | โ 1GB | โ Rest of RAM |
| Write-Heavy | โ Disabled | โ 1GB | โ Rest of RAM |
| Time-Series | โ Disabled | โ 500MB | โ Rest of RAM |
| Mixed Workload | โ ๏ธ 1-2GB (selective) | โ 1GB | โ Rest of RAM |
| Small Dataset | โ 1-2GB | โ 500MB | โ Rest of RAM |
Common Caching Configurations
Configuration 1: E-Commerce Product Catalog
Configuration 2: User Session Store
Configuration 3: IoT Time-Series
Configuration 4: Analytics (Large Scans)
๐ผ Interview Questions & Expert Answers
Master caching strategies for your interview!
Answer: Row cache stores entire rows in off-heap memory (0.5ms), key cache stores partition key locations (skips 5ms disk read), and OS page cache automatically caches SSTable blocks in remaining RAM (2-5ms).
| Cache Type | What It Caches | Speed | When to Use |
|---|---|---|---|
| Row Cache | Entire partitions | 0.5ms โกโกโก | Hot data, read-heavy, small rows |
| Key Cache | Partition key locations | 1-2ms โกโก | Always! (default on) |
| OS Cache | SSTable blocks | 2-5ms โก | Always! (automatic) |
Detailed Explanation:
Row Cache:
- Stores complete serialized partition data
- Hit = instant return from memory
- Miss = read from disk + cache for next time
- Invalidated on any write to partition
- Use for: Product catalogs, user profiles (read-heavy, hot data)
Key Cache:
- Maps partition key โ SSTable offset
- Skips partition index read from disk
- Saves 5-10ms per SSTable lookup
- Small memory footprint (200 bytes per key)
- Use for: Everything! Should always be enabled
OS Page Cache:
- Operating system caches file blocks automatically
- Uses all RAM not allocated to JVM/caches
- No configuration needed - just works!
- LRU managed by OS kernel
- Use for: Everything! Maximize by keeping JVM heap small (8-16GB)
Key Takeaway: Key cache and OS cache are always beneficial. Row cache only for specific read-heavy workloads with hot data!
Answer: Row cache can hurt performance when data is write-heavy (frequent invalidations), has large rows (wastes cache space), or has no clear hot data (low hit rate). It also uses off-heap memory that could be better used by OS page cache.
Scenarios Where Row Cache Hurts:
Problem 1: Write-Heavy Workload
- Every write invalidates entire partition from cache
- Cache constantly being invalidated and re-populated
- Cache hit rate drops to 20-30% (useless!)
- Wasting memory that could be used by OS cache
Problem 2: Large Rows
- 2GB cache / 100KB per row = only 20K rows cached
- Most rows never fit in cache (cache thrashing)
- OS page cache could cache 2GB of SSTable blocks instead
- OS cache benefits ALL tables, not just one
Problem 3: No Hot Data (Uniform Access)
- Time-series: Access mostly recent data (not same rows)
- Analytics: Large scans touch different data each time
- Random access: No pattern to cache
- Cache hit rate: 10-20% (waste of memory)
Problem 4: Memory Pressure
- Row cache uses off-heap memory (outside JVM)
- On 16GB server, 2GB row cache = less for OS cache
- OS cache benefits all reads, row cache only cached rows
- Better: Give memory to OS cache for universal benefit
When Row Cache Makes Sense:
| Factor | Good for Row Cache | Bad for Row Cache |
|---|---|---|
| Read/Write Ratio | 95%+ reads | < 80% reads |
| Row Size | < 1KB | > 10KB |
| Access Pattern | Hot data (top 10%) | Uniform or sequential |
| Cache Hit Rate | > 90% | < 70% |
Key Takeaway: Monitor row cache hit rate. If < 70%, disable it and let OS page cache do the work!
Answer: JVM heap 16GB (25%), row cache 2-4GB if applicable, key cache 1GB, leaving 45-47GB (70%) for OS page cache. The key is maximizing OS cache since it benefits all reads.
Recommended Allocation for 64GB Server:
Total: 64GB RAM
- JVM Heap: 16GB (25%) - Never exceed 32GB!
- Row Cache: 2-4GB (3-6%) - Only if read-heavy with hot data
- Key Cache: 1GB (1.5%) - Always enable
- OS Page Cache: 45-47GB (70%) - The magic happens here!
Configuration:
Why This Allocation?
JVM Heap (16GB):
- Enough for memtables, bloom filters, compression buffers
- Not too large (> 32GB causes long GC pauses)
- Sweet spot: 8-16GB for most workloads
Row Cache (2-4GB):
- Only if you have clear hot data (top 10% of rows)
- Size based on: hot_rows ร avg_row_size
- Example: 1M hot products ร 2KB = 2GB
- If no hot data, set to 0 and use that RAM for OS cache!
Key Cache (1GB):
- Formula: num_partitions ร 200 bytes
- 5M partitions ร 200 bytes = 1GB
- Should cache all partition keys if possible
- Monitor hit rate, increase if < 95%
OS Page Cache (43GB - Most Important!):
- Automatically caches frequently accessed SSTable blocks
- Benefits ALL tables, not just one
- No configuration needed - just maximize available RAM
- This is where most performance gains come from!
Alternative Configurations:
Key Principle: When in doubt, give more RAM to OS page cache! It's universally beneficial and requires zero configuration.
Answer: Monitor cache hit rates (row cache > 90%, key cache > 95%), read latency P99, disk I/O utilization, and cache size vs capacity. Poor hit rates or high disk I/O indicate caching issues.
Key Metrics to Monitor:
1. Cache Hit Rates
What Hit Rates Mean:
| Row Cache > 90% | โ Excellent! Hot data well-cached |
| Row Cache 70-90% | โ ๏ธ OK, consider increasing size |
| Row Cache < 70% | โ Disable it! Wasting memory |
| Key Cache < 95% | โ Increase size! |
2. Read Latency
Latency Breakdown:
- 0.5-2ms: Row cache hit (excellent!)
- 2-5ms: OS cache hit (good!)
- 10-20ms: Disk read (acceptable)
- > 50ms: Too many SSTables or slow disks (problem!)
3. Disk I/O Utilization
4. Cache Size vs Capacity
5. OS Memory Usage
Decision Matrix:
| Symptom | Diagnosis | Action |
|---|---|---|
| Row cache hit < 70% | No clear hot data | Disable row cache |
| Key cache hit < 95% | Cache too small | Increase key_cache_size_in_mb |
| High disk I/O (> 80%) | Cache misses | Add RAM or reduce heap |
| P99 latency > 50ms | Cold reads slow | Check SSTable count, compaction |
Monitoring Best Practices:
- โ Check cache hit rates daily
- โ Alert if row cache < 70% (disable it!)
- โ Alert if key cache < 95% (increase size!)
- โ Monitor P99 latency trends
- โ Track disk I/O utilization
Answer: Any write (update, delete, insert) to a partition invalidates the ENTIRE partition from row cache. For write-heavy workloads, this causes constant cache invalidation, resulting in low hit rates and wasted memory.
What Happens on Write:
- Write Arrives: UPDATE user SET name = 'Jane' WHERE user_id = 123
- Write to Commit Log: Written to disk (durable)
- Write to Memtable: In-memory write
- Invalidate Row Cache: ENTIRE partition for user_id=123 removed from cache!
- Acknowledge Write: Success returned to client
- Next Read: Cache miss โ read from disk โ cache again
Why Invalidate Entire Partition?
Row cache stores serialized partition data. Cassandra can't easily update just one column in cached data. Simpler/safer to invalidate entire partition and re-cache on next read.
Impact on Write-Heavy Workloads:
| Workload | Read/Write | Cache Hit Rate | Recommendation |
|---|---|---|---|
| Product Catalog | 99% read, 1% write | 95%+ โ | Enable row cache |
| User Profiles | 90% read, 10% write | 70-85% โ ๏ธ | Maybe (test it!) |
| Shopping Carts | 70% read, 30% write | 40-60% โ | Disable row cache |
| Sessions (active) | 60% read, 40% write | 20-30% โ | Disable row cache |
| Time-Series | 20% read, 80% write | < 10% โ | Disable row cache |
Real-World Example:
Key Takeaway: Row cache only helps when reads significantly outnumber writes (95%+ read ratio). For write-heavy workloads, disable it and use that memory for OS page cache!
๐ Chapter Summary: Caching Strategy Mastery
You now understand Cassandra's caching system at a production level!
The Three Cache Layers:
- ๐ฅ Row Cache: 0.5ms - Hot data only (read-heavy, hit rate > 90%)
- ๐ Key Cache: 1-2ms - Always enable! (saves 5-10ms per SSTable)
- ๐พ OS Page Cache: 2-5ms - Automatic! (maximize by keeping heap small)
Golden Rules:
- โ Always enable key cache - universally beneficial
- โ Maximize OS page cache - keep JVM heap 8-16GB
- โ ๏ธ Row cache only for read-heavy - 95%+ reads with hot data
- โ Disable row cache if hit rate < 70% - wasting memory
64GB Server Allocation:
JVM: 16GB | Row: 0-4GB | Key: 1GB | OS: 43-47GB
Remember Lisa: 100ms โ 0.5ms with proper caching! ๐
Responsive Ad