Scenario 05.2.2 · Tombstones & delete.retention.ms
Kafka tombstones: deleting a key with delete.retention.ms
A produced value=null tombstone deletes a key: compaction keeps it through the delete.retention.ms grace window, then a purge removes it for good.
Run this scenario in the playgroundDirty log · user-1 written twice. t+0.000s
A compacted topic with three records; user-1 was written twice (signup → email-verified). To DELETE user-2 from a compacted topic you publish a tombstone - a record with value=null for that key.
Open at this step: step 1, Dirty log · user-1 written twiceTombstone produced for user-2. t+0.300s
The producer appends a tombstone (value=null) at offset 3 for user-2. It is now the latest record for that key - a pending delete marker sitting in the dirty log.
Open at this step: step 2, Tombstone produced for user-2Compacted · tombstone kept. t+0.600s
Compaction keeps only the latest record per key: user-1 collapses to email-verified, and the user-2 tombstone SURVIVES (it must outlive the values it deletes). Survivors keep their original offsets, so gaps appear. The delete.retention.ms purge clock now starts. Real Kafka never compacts the active segment, so these records would first have to roll into a closed one.
Open at this step: step 3, Compacted · tombstone keptTombstone lingering (grace window). t+1.100s
Mid grace window: the tombstone still sits in the log. delete.retention.ms keeps it long enough for a consumer that reads within the window to observe the delete before it vanishes.
Open at this step: step 4, Tombstone lingering (grace window)Tombstone purged. t+1.600s
delete.retention.ms has elapsed: a tombstone_purge removes the user-2 marker too. Only user-1's latest value remains - the key is gone without a trace.
Open at this step: step 5, Tombstone purgedWhat you start with
On a compacted topic, producing a record with value=null is a tombstone that marks a key for deletion. Compaction keeps that tombstone around for delete.retention.ms so downstream consumers can observe the delete, then a later purge removes it permanently.
Step by step
- Dirty log · user-1 written twice t+0.000s A compacted topic with three records; user-1 was written twice (signup → email-verified). To DELETE user-2 from a compacted topic you publish a tombstone - a record with value=null for that key. Open at this step: step 1, Dirty log · user-1 written twice
- Tombstone produced for user-2 t+0.300s The producer appends a tombstone (value=null) at offset 3 for user-2. It is now the latest record for that key - a pending delete marker sitting in the dirty log. Open at this step: step 2, Tombstone produced for user-2
- Compacted · tombstone kept t+0.600s Compaction keeps only the latest record per key: user-1 collapses to email-verified, and the user-2 tombstone SURVIVES (it must outlive the values it deletes). Survivors keep their original offsets, so gaps appear. The delete.retention.ms purge clock now starts. Real Kafka never compacts the active segment, so these records would first have to roll into a closed one. Open at this step: step 3, Compacted · tombstone kept
- Tombstone lingering (grace window) t+1.100s Mid grace window: the tombstone still sits in the log. delete.retention.ms keeps it long enough for a consumer that reads within the window to observe the delete before it vanishes. Open at this step: step 4, Tombstone lingering (grace window)
- Tombstone purged t+1.600s delete.retention.ms has elapsed: a tombstone_purge removes the user-2 marker too. Only user-1's latest value remains - the key is gone without a trace. Open at this step: step 5, Tombstone purged
The takeaway
Tombstones delete keys from a compacted log, but delete.retention.ms holds them long enough for consumers to see the deletion before they finally disappear.
Configs in this scenario
-
delete.On a compacted topic, how long a tombstone (a record with a null value) stays in the log after compaction before it is removed too (default 86400000, 1 day); a consumer reading from the start must finish within it to see every delete. How delete.retention.ms worksretention. ms
Embed this scenario
Paste this into a blog post, a course page or your team's docs. The scenario plays inside your page, and the link under it points readers to this walkthrough.
<iframe src="https://monedula.dev/kafka-simulator/embed/?scenario=05.2.2" title="Kafka Simulator: Tombstones & delete.retention.ms" width="100%" height="520" style="border:1px solid #d0d0d0;border-radius:8px" loading="lazy"></iframe>
<p><a href="https://monedula.dev/kafka-simulator/scenarios/tombstones-delete-retention/">Kafka tombstones: deleting a key with delete.retention.ms</a></p> Further reading
More in Storage
- Kafka retention.ms and a consumer that falls behind
- Kafka retention.bytes: size-based log retention
- Kafka OFFSET_OUT_OF_RANGE with auto.offset.reset=none
- Kafka log compaction: cleanup.policy=compact explained
- Kafka cleanup.policy=compact,delete: both policies at once
- Kafka tiered storage: offloading old segments to remote
- Kafka tiered storage: a consumer reads from the remote tier
- Kafka local.retention.ms vs retention.ms in tiered storage
- Diskless Kafka topics (KIP-1163): the write path
- Diskless vs classic Kafka: cross-AZ replication traffic
- Diskless Kafka produce latency: the price of object storage