Apache Cassandra is an open-source, distributed wide-column database designed to store large volumes of data across many commodity servers with no single point of failure. Among database systems, Cassandra is classified as a NoSQL store: it organizes data in tables of rows and columns queried with the SQL-like Cassandra Query Language (CQL), but it gives up joins and general ad hoc queries in exchange for predictable performance at scale.
Cassandra was created at Facebook, released as open source in 2008 and became a top-level Apache Software Foundation project in 2010. Its design combines the peer-to-peer distribution model of Amazon’s Dynamo with the storage model of Google’s Bigtable, which explains both its strengths and its constraints.
How Cassandra distributes data
A Cassandra cluster is a ring of equal nodes without a leader or primary. Each row belongs to a partition, identified by the partition key, and a hash of that key, computed by default with the Murmur3 partitioner, determines which nodes own the partition. Using virtual nodes, each server owns many small token ranges, which spreads data evenly and speeds up rebalancing when nodes join or leave.
Every partition is stored on several nodes according to the replication factor, typically three per data center. The NetworkTopologyStrategy places replicas in different racks and data centers, so a cluster can survive the loss of a whole rack or region. Nodes learn about each other through a gossip protocol, and any node can act as the coordinator for a client request, forwarding it to the replicas that own the data.
Tunable consistency
Cassandra lets each read and write choose its consistency level, meaning how many replicas must respond before the operation succeeds. This makes the trade-off between latency, availability and consistency explicit per query rather than fixed for the whole system.
| Consistency level | Replicas that must respond | Typical use |
|---|---|---|
| ONE | 1 | Lowest latency, tolerates two replicas down |
| QUORUM | 2 of 3 across the cluster | Balanced consistency and availability |
| LOCAL_QUORUM | 2 of 3 in the local data center | Multi-region apps avoiding cross-region latency |
| ALL | 3 | Strongest guarantee, fails if any replica is down |
| ANY (writes only) | Any node, including a hint | Maximum write availability |
When the number of replicas written plus the number read exceeds the replication factor, for example QUORUM writes with QUORUM reads, every read overlaps at least one replica with the latest write, giving strongly consistent reads for single-partition operations. Replicas that missed writes are repaired through hinted handoff, read repair and scheduled anti-entropy repair. For compare-and-set operations, Cassandra offers lightweight transactions based on Paxos, which cost several round trips.
Storage engine and write path
Cassandra uses a log-structured merge-tree storage engine optimized for writes. A write is appended to the commit log for durability and inserted into an in-memory memtable; when the memtable fills, it is flushed to disk as an immutable SSTable. Nothing is updated in place, so writes are sequential and fast, which is why Cassandra handles very high write throughput on ordinary hardware.
Reads may need to combine data from the memtable and several SSTables. Bloom filters, partition indexes and caches reduce disk lookups, and compaction periodically merges SSTables and discards obsolete versions. Deletes are written as markers called tombstones, which are removed only after the gc_grace_seconds period, ten days by default, to prevent deleted data from reappearing on replicas that were offline.
| Strategy | Best for | Trade-off |
|---|---|---|
| Size-tiered (STCS) | Write-heavy workloads | Temporary disk space spikes, slower reads |
| Leveled (LCS) | Read-heavy workloads with updates | Higher write amplification |
| Time-window (TWCS) | Time series with TTL expiry | Poor fit for out-of-order updates |
| Unified (UCS) | General use in Cassandra 5.0 | Newer, requires tuning knowledge |
Data modeling for Cassandra
Cassandra requires query-first data modeling. Instead of normalizing entities and joining them at query time, designers start from the application’s queries and create one table per query pattern, duplicating data where necessary. The primary key has two parts: the partition key decides where data lives, and the clustering columns decide the sort order of rows inside the partition.
Good models keep partitions bounded, commonly well below about 100 MB and a few hundred thousand rows, and spread load evenly across partition keys. A table for sensor readings might use PRIMARY KEY ((sensor_id, day), reading_time), so each partition holds one sensor’s day and queries for a time range read one partition in order. Queries that filter on non-key columns require secondary indexes or `ALLOW FILTERING`, both of which scale poorly when used carelessly; Cassandra 5.0 adds storage-attached indexes that improve this situation.
Cassandra compared with other database systems
Cassandra sits between general-purpose relational databases and fully managed key-value services. The comparison below highlights where it fits.
| System | Data model | Main difference from Cassandra |
|---|---|---|
| Apache Cassandra | Wide-column, CQL | Leaderless, multi-region writes, tunable consistency |
| PostgreSQL | Relational, SQL | Joins and full transactions, single primary for writes |
| MongoDB | Document | Flexible documents, primary-based replica sets |
| Amazon DynamoDB | Key-value and document | Fully managed, similar partition-key modeling |
| CockroachDB | Distributed relational | Serializable SQL transactions, higher write latency |
| ClickHouse | Columnar analytics | Optimized for scans and aggregations, not point writes |
Cassandra is a strong choice for write-heavy, always-on workloads with known access patterns: time series, event logs, messaging, IoT telemetry and user activity feeds. It is a poor fit for workloads that need multi-row transactions, joins or flexible reporting, and for small datasets where a single relational server is simpler to operate.
Operational pitfalls
- Large or hot partitions overload individual nodes and cause timeouts; choose partition keys with high cardinality and bounded size.
- Tombstone accumulation from frequent deletes or nulls slows reads and can abort queries at the tombstone failure threshold.
- Skipping regular repair within the
gc_grace_secondswindow can resurrect deleted data. - Treating CQL like SQL, with filters on unindexed columns or batches across many partitions, defeats the distributed design.
In simple terms
Apache Cassandra is a database that spreads data over many computers at once, often in several cities. Each piece of data is copied to a few of those computers. If one machine or even a whole building goes offline, the others keep answering.
The price for this resilience is planning. Designers must decide in advance how the data will be looked up, much like arranging a warehouse around the orders it will ship.
A practical example
A company that operates smart electricity meters collects a reading from each of two million meters every fifteen minutes. The team stores the readings in Cassandra across three data centers with a replication factor of three in each. The table is keyed by meter and month, with the reading time as a clustering column, and uses time-window compaction with a TTL of two years.
Meters write at consistency level ONE so that ingestion never stalls, while the billing service reads at LOCAL_QUORUM to get consistent monthly totals. During a planned outage of one data center, ingestion continues without interruption in the other two, and the returning data center catches up through hints and repair. The billing queries each read a single partition per customer, so their latency stays stable as the dataset grows.