skip to content

What does cleanup.policy=delete mean for a Kafka topic, and how does Kafka decide which data to remove?

level: juniorimportance: must knowfreq 72%

answer

  1. delete = age out by time or size
  2. default policy, 7 days
  3. whole segments, not records
  4. active segment never deleted
  5. time OR size — stricter wins

basics

~10 s

cleanup.policy=delete means old log data is discarded once it exceeds a time or size limit. Kafka deletes whole log segments older than the retention time, or to keep the partition under the size cap.

solid answer

~40 s

cleanup.policy=delete is the default retention mode for a Kafka topic. Instead of keeping data forever, Kafka removes old records once they pass a retention threshold. Two thresholds apply per partition: time (log.retention.ms / .minutes / .hours) and size (retention.bytes). Deletion is not per-record — Kafka's log is split into segment files, and a background retention thread deletes whole segments that are fully past the limit. The active (currently-written) segment is never deleted. This is different from cleanup.policy=compact, which keeps the latest value per key instead of dropping by age. delete is what you want for event streams, logs, and metrics where old data simply expires; compact is for changelog/state topics where you need the current value per key indefinitely.

go deeper

for a junior

Know that delete = data expires by age/size and it's the default; contrast with compact.

for a middle

Explain time vs size thresholds and that deletion happens at segment granularity, not per record.

for a senior

Discuss the retention thread, active-segment exemption, and how segment.bytes/segment.ms bound when data actually leaves.

for a principal

Reason about choosing delete vs compact per data semantics and the operational implications for slow consumers and disk sizing.

## What a Kafka topic stores A Kafka **topic** is split into **partitions**; each partition is an append-only **log** persisted on disk. Producers append records to the end (the *head*); consumers read forward by *offset* (a monotonically increasing record position). Because the log only grows, Kafka needs a policy to bound disk usage — that is what `cleanup.policy` controls. ## The two policies - `cleanup.policy=delete` (the default): records are removed once they age out by **time** or **size**. Old data is simply gone. - `cleanup.policy=compact`: Kafka instead keeps the **latest record per key** and removes superseded older values. (Compaction is a sibling topic and not covered here.) You can set both (`delete,compact`) to compact and also cap retention, but the pure-delete case is the focus here. ## How delete decides what to remove Retention is evaluated **per partition** against two limits: - **Time**: `log.retention.ms` (or `.minutes`/`.hours`, with `.ms` winning if several are set). Default is 7 days (`168` hours). A record is eligible once it is older than this. - **Size**: `retention.bytes` — the maximum bytes to keep per partition. Default `-1` (unlimited). When the partition exceeds this, oldest data is removed until it fits. If **both** are set, a segment is removed when **either** limit says it should be — i.e. the more aggressive limit wins. ## Granularity: segments, not records Kafka does not delete individual records. Each partition log is divided into **segment files** (default `segment.bytes=1 GiB`, or rolled by `segment.ms`). A background **retention thread** scans closed (non-active) segments and deletes an entire segment only once **all** records in it are past the limit (based on the segment's largest timestamp for time retention). The **active segment** — the one currently being appended to — is never deleted. This means data can live somewhat past its nominal retention until its segment closes and is fully expired. ## When to use it Use `delete` for event streams, click/telemetry data, application logs, and metrics — anything where old records lose value and you just want a rolling window. Use `compact` when the topic represents the *current state per key* (e.g. a database changelog) that must survive indefinitely. ## Edge cases - Lowering retention does **not** instantly purge data; it takes effect when the retention thread next runs and segments roll/close. - Setting `retention.ms=0` (or a tiny value) effectively makes records eligible almost immediately, but the active segment still survives until it rolls. - Consumer offsets are independent of retention — if data is deleted before a slow consumer reads it, that consumer gets an `OffsetOutOfRange` and must reset.

  • What is the default retention time for a delete-policy topic?
    7 days (log.retention.hours=168), unless overridden by log.retention.minutes/ms or the per-topic retention.ms.
  • Does deleting old data move or change consumer offsets?
    No. Offsets are independent; deleted records just become unreadable. A consumer whose committed offset points at deleted data gets OffsetOutOfRange and follows its auto.offset.reset policy.

saying these in an interview costs you the question

  • Saying Kafka deletes records one at a time (it deletes whole segments).
  • Claiming the active segment can be deleted by retention.
  • Confusing delete with compaction (keeping latest per key).
  • Thinking lowering retention.ms instantly frees disk.

context