| name | cassandra |
| description | Cassandra — partition keys, CQL, consistency levels, CLI. |
Cassandra Reference
When to Load
Load when the project uses Cassandra or ScyllaDB (signal: cassandra-driver, cassandra-python-driver, datastax-astra, cassandra: in docker-compose, CASSANDRA_HOST env var).
CLI Connection
cqlsh "$CASSANDRA_HOST" "${CASSANDRA_PORT:-9042}" \
-u "$CASSANDRA_USER" -p "$CASSANDRA_PASSWORD"
cqlsh "$CASSANDRA_HOST" 9142 --ssl \
-u "$CASSANDRA_USER" -p "$CASSANDRA_PASSWORD"
cqlsh -b "$ASTRA_BUNDLE_PATH" -u "$ASTRA_CLIENT_ID" -p "$ASTRA_SECRET"
Key inspection commands:
DESCRIBE KEYSPACES;
DESCRIBE TABLES;
DESCRIBE TABLE keyspace.table;
SELECT * FROM system.local;
SELECT * FROM system.peers;
TRACING ON;
Data Model — Think in Queries
Cassandra requires query-driven data modeling. Unlike relational databases, denormalization is expected.
Primary key anatomy:
PRIMARY KEY ((partition_key), clustering_col1, clustering_col2)
- Partition key: determines which node holds the data; must appear in every query (
WHERE partition_key = ?)
- Clustering columns: physical sort order within the partition; enable range queries
- All data within a partition is stored together; partitions should stay under ~100 MB
Design rules:
- Know your queries before designing the table
- One table per query pattern is normal
- Avoid large partitions (millions of rows in one partition → hotspot)
- Avoid unbounded clustering columns — add a time-bucket to partition key if inserting time series
CQL Essentials
CREATE TABLE user_sessions (
user_id UUID,
session_id UUID,
data TEXT,
PRIMARY KEY (user_id, session_id)
) WITH default_time_to_live = 86400;
INSERT INTO user_sessions (user_id, session_id, data)
VALUES (?, ?, ?) USING TTL 3600;
INSERT INTO users (id, email) VALUES (?, ?) IF NOT EXISTS;
UPDATE users SET email = ? WHERE id = ? IF email = ?;
Consistency Levels
| Level | Reads from | Writes to | Trade-off |
|---|
ONE | 1 replica | 1 replica | Fastest; risk of stale reads |
QUORUM | Majority | Majority | Strong consistency across DC |
LOCAL_QUORUM | Majority in local DC | Majority in local DC | Low latency in multi-DC |
ALL | All replicas | All replicas | Strongest; not fault-tolerant |
EACH_QUORUM | Quorum per DC | Quorum per DC | Geo-distributed writes |
Strong consistency rule: read CL + write CL > replication factor
- RF=3, write
QUORUM (2) + read QUORUM (2) = 4 > 3 → strongly consistent
Default recommendation: write LOCAL_QUORUM, read LOCAL_QUORUM for most OLTP workloads.
Compaction Strategies
| Strategy | Best for |
|---|
SizeTieredCompactionStrategy (default) | Write-heavy; infrequent reads; heavy data |
LeveledCompactionStrategy | Read-heavy; predictable read latency; smaller SSTables |
TimeWindowCompactionStrategy | Time series with TTL; groups SSTables by time window |
Change strategy: ALTER TABLE t WITH compaction = {'class': 'LeveledCompactionStrategy'};
Secondary Indexes & Materialized Views
- Secondary indexes: avoid on high-cardinality columns or on columns used without the partition key — causes scatter reads across all nodes
- Materialized Views: maintained by Cassandra; trades write overhead for read convenience; use carefully (risk of write amplification and consistency lag)
- SAI (Storage-Attached Index): Cassandra 4.x / DataStax; column-level index without full-table scatter; prefer over legacy secondary indexes
Tombstones & Deletion
- Deletes write a tombstone (not an immediate removal); tombstones are removed during compaction
- Excessive tombstones (> 100k per read) cause read timeouts — monitor with
nodetool tpstats
- Use TTL instead of explicit deletes for time-expiring data
- Never issue
TRUNCATE in production without checking dependent materialized views
Common Gotchas
| Gotcha | Fix |
|---|
ALLOW FILTERING in query | Re-model the table for the query or add a SAI index |
| Hotspot partition (one partition grows unbounded) | Add a time-bucket to the partition key |
| Lightweight transactions (IF NOT EXISTS) slow | Use sparingly — they use Paxos; not for hot paths |
Reading with IN on partition key | May cause coordinator hotspot; prefer parallel single-partition reads |
nodetool repair not scheduled | Run weekly on each node; skipping causes inconsistency and tombstone accumulation |