Monedula

Scenario 05.3.2 · Reading from the remote tier

Kafka tiered storage: a consumer reads from the remote tier

Storage · Advanced · about 3 min · Apache Kafka 4.3

An offloaded prefix raises localStartOffset; a lagging consumer reading below it is served from remote (remote_read), then crosses back into the local log.

Run this scenario in the playground

Crossed into the local log - caught up. t+3.800s

The final poll starts at offset 6 = localStartOffset, so these records come straight from the LOCAL log - no remote_read. Offsets 6-8 are delivered and the position catches up to the high watermark (9). Tiered storage is transparent to the consumer: it read all 9 records, remote then local, with nothing lost.

Open at this step: step 6, Crossed into the local log - caught up

What you start with

Once a prefix is offloaded to the remote tier, the partition localStartOffset rises above logStartOffset. A consumer reading below localStartOffset is served from remote storage (a remote_read) until it catches up and crosses back into the locally retained log (KIP-405 tiered storage).

Step by step

  1. Remote storage on · consumer offline t+0.000s The topic has remote.storage.enable=true. The consumer c1 is taken offline (kill_consumer) so it falls behind while the old prefix is offloaded - its committed position stays at 0. Open at this step: step 1, Remote storage on · consumer offline
  2. 9 records produced - all in the local log t+0.600s Producer p1 writes 9 records (offsets 0-8). The high watermark is 9 and every record still lives on the broker's LOCAL log: localStartOffset is unset (= logStartOffset = 0), so nothing has been tiered yet. Open at this step: step 2, 9 records produced - all in the local log
  3. Old prefix offloaded to remote t+1.000s tier_offload copies the [0,6) prefix to the remote tier and raises localStartOffset to 6. The records aren't deleted - they're just no longer on local disk. The local log now begins at offset 6; offsets 0-5 live only in remote storage but stay fully readable. Open at this step: step 3, Old prefix offloaded to remote
  4. Poll from offset 0 - served from remote t+2.200s The consumer comes back (restart_consumer) and polls from offset 0. Because 0 is below localStartOffset (6), the broker serves those records from the REMOTE tier - a remote_read at offset 0. max.poll.records=3 returns offsets 0-2; the position advances to 3, still below localStartOffset. Open at this step: step 4, Poll from offset 0 - served from remote
  5. Still below localStartOffset - remote again t+3.000s The next poll starts at offset 3 - still below localStartOffset (6) - so it is another remote_read (at offset 3), delivering offsets 3-5. The position reaches 6: the consumer has drained the entire offloaded prefix from remote storage. Open at this step: step 5, Still below localStartOffset - remote again
  6. Crossed into the local log - caught up t+3.800s The final poll starts at offset 6 = localStartOffset, so these records come straight from the LOCAL log - no remote_read. Offsets 6-8 are delivered and the position catches up to the high watermark (9). Tiered storage is transparent to the consumer: it read all 9 records, remote then local, with nothing lost. Open at this step: step 6, Crossed into the local log - caught up

The takeaway

Reads below localStartOffset transparently fetch from the remote tier - the consumer sees one continuous log and pays only extra latency for the offloaded segments.

Configs in this scenario

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.3.2" title="Kafka Simulator: Reading from the remote tier" width="100%" height="520" style="border:1px solid #d0d0d0;border-radius:8px" loading="lazy"></iframe>
<p><a href="https://monedula.dev/kafka-simulator/scenarios/reading-from-remote-tier/">Kafka tiered storage: a consumer reads from the remote tier</a></p>

Further reading

Apache Kafka documentation

More in Storage

All scenarios