# Cassandra Compaction Strategies: STCS, LCS, TWCS, and UCS Performance Guide

> Master Cassandra compaction strategies STCS LCS TWCS and UCS. Understand write read amplification tradeoffs for optimal performance in your Cassandra database.

- Repository: [The Apache Software Foundation/cassandra](https://github.com/apache/cassandra)
- Tags: performance
- Published: 2026-07-29

---

**Cassandra offers four compaction strategies—Size-Tiered (STCS), Leveled (LCS), Time-Window (TWCS), and Unified (UCS)—each trading off write amplification against read amplification to optimize for write-heavy, read-heavy, time-series, or mixed workloads respectively.**

The **apache/cassandra** repository implements these strategies as pluggable algorithms that control how immutable SSTables are merged and rewritten on disk. Selecting the appropriate **Cassandra compaction strategy** for your table directly determines write amplification, read latency, and storage overhead.

## How Cassandra Compaction Works

Cassandra stores data on disk in immutable **SSTables**. Over time, these files accumulate, become fragmented, and retain obsolete rows and tombstones. Compaction is the background process that selects groups of SSTables, merges them, discards deleted data, and writes new, consolidated SSTables. The strategy you choose dictates *how* SSTables are grouped and *when* they are merged.

## Size-Tiered Compaction Strategy (STCS)

**STCS** groups SSTables of similar size into buckets and compacts the hottest bucket when it reaches configurable thresholds. This is the default strategy for tables without an explicit compaction setting.

The implementation lives in [[`SizeTieredCompactionStrategy.java`](https://github.com/apache/cassandra/blob/main/SizeTieredCompactionStrategy.java)](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/SizeTieredCompactionStrategy.java). The strategy builds size buckets via `getBuckets` and selects the most "interesting" bucket based on read hotness and size thresholds at [lines 97-104](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/SizeTieredCompactionStrategy.java#L97-L104).

Compaction fires whenever enough SSTables of comparable size exist, using defaults of `min_threshold = 4` and `max_threshold = 32`.

- **Write amplification**: Low, because only similar-sized SSTables are merged at once.
- **Read amplification**: High, as many small SSTables may need scanning for a single read.
- **Space amplification**: Moderate, up to approximately 2× data size, because older data lingers until thresholds are met.

## Leveled Compaction Strategy (LCS)

**LCS** organizes SSTables into levels where each level holds SSTables of roughly the same size. Compacting a level produces SSTables for the next level, ensuring that each level is 10 times larger than the previous by default.

The core logic resides in [[`LeveledCompactionStrategy.java`](https://github.com/apache/cassandra/blob/main/LeveledCompactionStrategy.java)](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/LeveledCompactionStrategy.java) with supporting calculations in [[`LeveledGenerations.java`](https://github.com/apache/cassandra/blob/main/LeveledGenerations.java)](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/LeveledGenerations.java). The strategy maintains a manifest of levels and selects candidates from the lowest non-empty level via `getCompactionCandidates()` at [lines 50-54](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/LeveledCompactionStrategy.java#L50-L54).

A level compacts when it exceeds the configured **fan-out** (default 10) or when an SSTable exceeds `sstable_size_in_mb`.

- **Write amplification**: High, because data is rewritten multiple times as it cascades through levels.
- **Read amplification**: Low—at most one SSTable per level needs consultation, providing logarithmic read scaling.
- **Space amplification**: Predictable, bounded at roughly 2× data size due to strict level size limits.

## Time-Window Compaction Strategy (TWCS)

**TWCS** specializes STCS for time-series data by creating time-based buckets (e.g., hourly or daily) based on row timestamps. It compacts SSTables only within their respective time windows.

The implementation is found in [[`TimeWindowCompactionStrategy.java`](https://github.com/apache/cassandra/blob/main/TimeWindowCompactionStrategy.java)](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/TimeWindowCompactionStrategy.java), with option parsing in [[`TimeWindowCompactionStrategyOptions.java`](https://github.com/apache/cassandra/blob/main/TimeWindowCompactionStrategyOptions.java)](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/TimeWindowCompactionStrategyOptions.java). The strategy creates time buckets via `newestBucket` and delegates to STCS for intra-bucket compaction at [lines 308-330](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/TimeWindowCompactionStrategy.java#L308-L330).

- **Write amplification**: Low for recent windows, but dramatically lower for older data because historic windows are compacted once and then left untouched.
- **Read amplification**: Low—one SSTable per time window for old data, few SSTables for recent windows.
- **Space amplification**: Minimal for old windows (single SSTable), modest for recent windows.

## Unified Compaction Strategy (UCS)

**UCS** is a hybrid strategy that automatically selects between STCS, LCS, and TWCS behaviors based on table metadata and workload characteristics. It provides a "set-and-forget" configuration for mixed workloads.

The core implementation is in [[`UnifiedCompactionStrategy.java`](https://github.com/apache/cassandra/blob/main/UnifiedCompactionStrategy.java)](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/UnifiedCompactionStrategy.java), controlled by [[`Controller.java`](https://github.com/apache/cassandra/blob/main/Controller.java)](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/unified/Controller.java). UCS computes a scaling parameter `W` that determines whether it behaves like size-tiered or leveled compaction at [lines 253-259](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/unified/Controller.java#L253-L259).

For tables with a `compaction_window`, it behaves like TWCS; otherwise, it falls back to size-tiered or leveled mode based on the scaling parameter.

- **Write amplification**: Balanced—UCS attempts to maintain STCS-level write costs unless LCS benefits outweigh the overhead.
- **Read amplification**: Adaptive, usually remaining below STCS levels while approaching LCS efficiency when read hotness is high.
- **Complexity**: Higher runtime decision-making can lead to unpredictable compaction patterns in edge cases.

## Performance Implications and Trade-offs

| Strategy | Write Amplification | Read Amplification | Space Amplification | Compaction Latency |
|----------|---------------------|--------------------|---------------------|--------------------|
| **STCS** | Low | High | ~2× data size | Short, frequent tasks |
| **LCS** | High | Low (log-scale) | ~2× data size | Longer, less frequent tasks |
| **TWCS** | Low for recent, negligible for old | Low | Minimal for old windows | Predictable, isolated to newest window |
| **UCS** | Moderate (adaptive) | Adaptive | Similar to dominant sub-strategy | Mixed, depends on mode switching |

Choosing between these strategies requires balancing **write cost** (how many times data is rewritten) against **read cost** (how many SSTables must be consulted). For write-heavy, uniformly accessed tables, STCS or UCS with a low scaling parameter is optimal. For read-heavy tables with frequent point lookups, LCS provides the best latency. Time-series workloads benefit most from TWCS or UCS when `compaction_window` is configured.

## Configuring Compaction Strategies in CQL

You configure compaction strategies using the `WITH compaction` clause in CQL. The [[`CompactionStrategyManager.java`](https://github.com/apache/cassandra/blob/main/CompactionStrategyManager.java)](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/CompactionStrategyManager.java) serves as the central façade that invokes your chosen strategy.

### Default Size-Tiered Configuration

```sql
CREATE TABLE sensor_data (
    device_id uuid,
    ts timestamp,
    value double,
    PRIMARY KEY (device_id, ts)
);

```

### Leveled Compaction for Read-Heavy Workloads

```sql
CREATE TABLE user_profile (
    user_id uuid PRIMARY KEY,
    name text,
    email text
) WITH compaction = {
    'class': 'LeveledCompactionStrategy',
    'sstable_size_in_mb': '160',
    'fanout_size': '10'
};

```

The `LeveledCompactionStrategy` constructor reads `sstable_size_in_mb` and `fanout_size` options at [lines 88-107](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/LeveledCompactionStrategy.java#L88-L107).

### Time-Window Compaction for Time-Series Data

```sql
CREATE TABLE metric_points (
    metric_id uuid,
    day date,
    ts timestamp,
    value double,
    PRIMARY KEY ((metric_id, day), ts)
) WITH compaction = {
    'class': 'TimeWindowCompactionStrategy',
    'compaction_window_unit': 'DAYS',
    'compaction_window_size': '1'
};

```

The `TimeWindowCompactionStrategyOptions` class parses `compaction_window_unit` and `compaction_window_size` at [lines 62-84](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/TimeWindowCompactionStrategyOptions.java#L62-L84).

### Unified Compaction for Mixed Workloads

```sql
CREATE TABLE events (
    event_id uuid PRIMARY KEY,
    payload blob,
    created timestamp
) WITH compaction = {
    'class': 'UnifiedCompactionStrategy',
    'scaling_parameter': '0.5'
};

```

Smaller scaling parameters produce STCS-like behavior, while larger values shift toward LCS-like operation. The `Controller` validates options and parses the scaling parameter at [lines 249-262](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/unified/Controller.java#L249-L262).

## Summary

- **Size-Tiered Compaction (STCS)** minimizes write amplification but increases read amplification, making it ideal for high-throughput write workloads.
- **Leveled Compaction (LCS)** optimizes for read-heavy workloads by ensuring data is spread across a minimal number of SSTables, at the cost of higher write amplification.
- **Time-Window Compaction (TWCS)** isolates time-series data into discrete windows, providing excellent read performance for recent data while freezing historical windows.
- **Unified Compaction (UCS)** automatically adapts between strategies based on workload characteristics, simplifying configuration for mixed-use cases.
- All strategies are implemented in `org.apache.cassandra.db.compaction` and configured via the `WITH compaction` CQL syntax.

## Frequently Asked Questions

### What is the default Cassandra compaction strategy?

The default strategy is **Size-Tiered Compaction Strategy (STCS)**. When you create a table without specifying a compaction class, Cassandra uses `SizeTieredCompactionStrategy` with default thresholds of 4 minimum and 32 maximum SSTables per compaction.

### How does Leveled Compaction Strategy improve read performance?

LCS improves read performance by guaranteeing that each level contains non-overlapping SSTables of exponentially increasing size. As implemented in [`LeveledCompactionStrategy.java`](https://github.com/apache/cassandra/blob/main/LeveledCompactionStrategy.java), this ensures that read operations consult at most one SSTable per level, resulting in logarithmic read amplification relative to data volume.

### When should I use Time-Window Compaction Strategy over Size-Tiered?

Use TWCS when your workload involves **time-series data** where recent partitions receive heavy writes but older partitions are rarely accessed. According to the `TimeWindowCompactionStrategy` implementation, this strategy prevents compaction from rewriting historical data, reducing both write amplification and compaction overhead for old SSTables compared to STCS.

### Can I change the compaction strategy on an existing table?

Yes, you can alter the compaction strategy using `ALTER TABLE ... WITH compaction = {'class': 'NewStrategy'}`. However, existing SSTables remain in their current format until they are compacted by the new strategy. The transition may trigger immediate major compactions, so plan for temporary increased I/O and disk space usage during the migration period.