Using Cassandra TTL to Automate Stale‑Data Cleanup – What You Need to Know
Learn how Cassandra’s built‑in TTL feature can automatically expire data, why it creates tombstones, and how to monitor and tune it to avoid performance surprises.
07 Nov 2025, 18:58 UTC

Problem: Stale data piles up and costs you
Many applications generate data that only has value for a limited time—session tokens, telemetry readings, or temporary caches. If that data stays in Cassandra forever, storage grows, backups take longer, and you may run afoul of data‑retention policies. Manually deleting rows with periodic jobs adds operational complexity and risk of mistakes.
Thesis: Cassandra TTL automates expiration but shifts work to compaction
Cassandra’s USING TTL clause lets you attach an expiration timestamp to each column (or the whole row) at write time. The database tracks the remaining time and, once it reaches zero, marks the data as a tombstone. During the next compaction, those tombstones are removed, freeing disk space. The benefit is no external delete jobs; the trade‑off is extra tombstone pressure until compaction runs.
How TTL works in CQL
When you create a table, you can insert data with a TTL value measured in seconds:
INSERT INTO events (event_id, payload)
VALUES (uuid(), 'sensor‑reading‑123')
USING TTL 86400;
The USING TTL 86400 clause tells Cassandra to treat the row as expiring after 24 hours. You can check the remaining time at any moment:
SELECT ttl(payload) FROM events WHERE event_id = ?;
The query returns a countdown value that decreases each second. After the TTL expires, the row becomes a tombstone; it remains visible to reads until a compaction process purges it.
Worked example: Insert, verify, and observe tombstones
- Insert a row with TTL (run in cqlsh or a driver session):
INSERT INTO events (event_id, payload) VALUES (now(), 'test') USING TTL 300; - Check the TTL immediately**:**
SELECT ttl(payload) FROM events WHERE event_id = ?;
You should see a value close to 300. - Wait a few seconds and query again**:**
The returned TTL will have dropped, confirming the internal countdown. - After the TTL passes (here, 5 minutes)**:**
RunSELECT * FROM events WHERE event_id = ?;– the row will still appear because the tombstone hasn’t been compacted yet. - Inspect tombstone count**:**
From a shell on any node:nodetool tablestats mykeyspace events
Look for the “Tombstones” field; it should be non‑zero after expiration. - Trigger compaction (optional for testing)**:**
nodetool compact mykeyspace events
After compaction finishes, the tombstone count drops and the reclaimed space appears in the “Space used (live)” metric.
This sequence shows that TTL works as advertised, but also that tombstones linger until compaction runs.
Trade‑off: Tombstone pressure and compaction load
Each expired row leaves a tombstone. Until the next compaction, those tombstones:
- Increase disk usage (the tombstone record still occupies space).
- Add read‑path latency because Cassandra must check tombstones to determine if a column is live.
- Can cause repair traffic to spike, as tombstones must be streamed to replicas during anti‑entropy.
If your workload generates a high write‑to‑delete ratio (lots of short‑TTL inserts), you may see:
- More frequent compaction cycles.
- Higher I/O and CPU usage on the compaction threads.
- Need for larger disk provisioning or a compaction strategy optimized for tombstone handling, such as
LeveledCompactionStrategy(LCS) orTimeWindowCompactionStrategy(TWCS) when you can bucket data by time windows.
Actionable advice: Validate before you rely on TTL
- Measure your write‑to‑delete ratio**:** In a staging cluster, insert a known volume of rows with your target TTL and monitor
nodetool tablestatsover time. Track how quickly the tombstone count rises and how often compaction is triggered. - Monitor tombstone metrics**:** Use
nodetool tablestatsor JMX metrics likeLiveDiskSpaceUsedandTombstoneCount. Set alerts if tombstone growth exceeds a threshold (e.g., >10% of live data). - Tune compaction**:** If you see constant compaction backpressure, consider switching to LCS for workloads with uniform tombstone distribution, or TWCS if you can partition data by time windows (e.g., one table per day).
- Adjust TTL values**:** If tombstone pressure is too high, increase the TTL to reduce the rate of expiration, or batch deletions manually for cold data.
- Test in production‑like load**:** Run a mixed read/write workload with your TTL settings and verify that read latency stays within SLA after compaction catches up.
Closing: Let Cassandra do the cleanup, but watch the side effects
Cassandra TTL removes the need for external delete jobs and guarantees that data disappears after a set interval. The mechanism is reliable across Cassandra 3.x and 4.x, but it shifts the cleanup burden to compaction in the form of tombstones. By measuring tombstone accumulation, choosing an appropriate compaction strategy, and validating TTL behavior in a staging environment, you can reap the automation benefits without surprising latency spikes or storage overruns.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.