Cassandra TimeWindowCompactionStrategy: When Time‑Based Buckets Outperform Size‑Based Merging
Cassandra’s TimeWindowCompactionStrategy aligns compaction with TTL‑based time‑series data, offering lower I/O for immutable streams while requiring careful bucket sizing and verification.
27 Sept 2025, 18:01 UTC

The Problem: Immutable Time‑Series Streams
When you ingest thousands of sensor readings each second, each write creates an SSTable that may never be updated again. With SizeTieredCompactionStrategy (STCS) every write eventually triggers compactions that merge SSTables of similar size. For time‑series data that is append‑only, these compactions waste I/O because they merge immutable old data that offers no benefit.
Thesis: TWCS Aligns Compaction with Data Lifecycle
TimeWindowCompactionStrategy (TWCS) groups SSTables into fixed time windows (buckets) and compacts only within the current bucket. Once a bucket closes, it is largely left untouched except for tombstone cleanup. This matches the lifecycle of append‑only time‑series tables where recent rows are hot, older rows expire via TTL and rarely change.
How TWCS Works
TWCS creates buckets based on the timestamp column or write time, using the configurable compaction_window_unit (DAYS, HOURS, MINUTES) and compaction_window_size. By default the unit is DAYS and the size is 1, yielding daily buckets. Within an open bucket, TWCS behaves like STCS, merging SSTables of comparable size. After a bucket’s time window expires, only tombstone compaction runs during unchecked_tombstone_compaction, leaving the bucket’s data largely intact. The bucket closure occurs when the current window’s time span expires, at which point the coordinator marks the bucket as closed and only runs unchecked_tombstone_compaction, which removes deleted rows without rewriting data.
Worked Example: Sensor Readings Table
CREATE TABLE sensor_readings (
device_id text,
metric_time timestamp,
temperature double,
humidity double,
PRIMARY KEY (device_id, metric_time)
) WITH compaction = {
'class': 'TimeWindowCompactionStrategy',
'compaction_window_unit': 'DAYS',
'compaction_window_size': '1'
} AND default_time_to_live = 2592000; -- 30 days
With this configuration, writes for a given day belong to one bucket. A new bucket starts at midnight. Reads for recent data touch fewer SSTables than with STCS. Data older than the 30‑day TTL is tombstone‑compacted, but may remain on disk for up to one day beyond the TTL because bucket boundaries are coarse.
Trade‑offs and Limitations
- Read amplification across buckets: Queries that span multiple days must merge results from several bucket SSTables, increasing coordinator merge overhead.
- No historical updates: Changing a row from last week does not trigger re‑compaction of that bucket; stale versions persist until tombstone cleanup or bucket expiry.
- Bucket‑aligned TTL: Data can survive past its nominal TTL by up to one bucket period. A 1‑hour bucket with a 24‑hour TTL means data may linger up to 25 hours.
- Major compaction on migration: Switching an existing table to TWCS initiates a full table compaction, temporarily requiring additional disk space roughly equal to the table size.
- Cross‑window queries may suffer higher latency: The coordinator must gather results from multiple bucket SSTables, which can increase merge time and overall response latency.
Actionable Decision Framework
Choose TWCS when:
- Data is append‑only or immutable after write
- Updates are limited to recent time windows
- TTL is the primary expiration mechanism
- Read patterns are predominantly within recent buckets
To verify suitability, run the following checks:
- Confirm the compaction class via
SELECT compaction_strategy, compaction_strategy_options FROM system_schema.tables WHERE keyspace_name = 'your_keyspace' AND table_name = 'sensor_readings'; - Execute
nodetool cfstatson the table and verify that SSTable counts drop within the active bucket while older buckets stay stable. - Use
TRACING ONin cqlsh to compare read latency and SSTable counts for recent versus older partitions. - Test the strategy change on a staging cluster first, monitoring disk usage during the major compaction before applying to production.
Monitor disk usage during strategy changes. Use nodetool cfstats to track SSTable counts per bucket. For queries crossing buckets, consider materialized views or secondary indexes if latency becomes problematic.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.