Tiered Storage in Kafka

Tiered Storage in Kafka

How Kafka keeps fresh data on fast local disks and older data in cheap object storage, so you can keep months of events without paying for months of expensive broker disks.

Picture a busy restaurant kitchen. The chef keeps salt, oil and today’s vegetables within arm’s reach, because they are used every minute. The boxes of dried goods for the next three months sit in a storeroom down the hall. Nobody puts three months of flour on the cooking counter. There would be no room left to cook.

For most of its life, Apache Kafka worked like a kitchen where everything had to sit on the counter. Every message, whether it arrived a second ago or a year ago, lived on the local disks of the Kafka servers. Tiered storage is Kafka’s storeroom. Fresh data stays on fast local disks, older data moves to cheap and almost unlimited object storage such as Amazon S3, and applications keep reading it exactly as before. This guide explains what that means, how it works inside the broker, what it costs, and where it can hurt you if you are careless.

1The Problem: Kafka Loves Disks, and Disks Are Expensive

Before we learn the solution, we need to feel the pain it removes. Tiered storage exists because of one uncomfortable fact about how Kafka was built.

Storage and compute were glued together

A Kafka broker is a server that receives messages from producers, stores them, and hands them to consumers. In classic Kafka, each broker stores its share of the data on its own attached disks. The same machine that does the work of handling network traffic also holds all the bytes. Engineers call this a shared-nothing design, because no broker depends on a central storage system.

This design was a great choice in the early years. Local disks are fast, and Kafka reads and writes them in a straight line, which is the fastest way a disk can be used. But it has a hidden cost. When you want to keep more data, you must add more disk. And the only way to add more disk is to add more brokers, or buy bigger disks for every broker.

Analogy

Imagine a bakery where the only way to store more flour is to build another whole bakery, with new ovens, new bakers and new counters. You do not need more ovens. You only need more shelves. But the shelves and the ovens are sold as one package. That is classic Kafka storage.

Why this hurts in real life

Suppose a company ingests 2 terabytes of events per day and wants to keep 30 days of history so that new applications can replay old data. That is 60 terabytes of unique data. Kafka normally keeps three copies of every byte for safety, so the cluster needs about 180 terabytes of disk. To hold that much, the team may run dozens of brokers whose CPUs are barely busy. They are paying for compute they do not need, just to rent disk space.

3x
typical number of copies of every byte kept by replication
Hours
to move a big partition to a new broker in classic Kafka
Days to Years
how long teams often wish they could keep events

Three separate pains

Cost

Paying for idle machines

Brokers are added for disk, not for traffic. CPU, memory and network sit unused while the bill keeps growing.

Operations

Slow, risky rebalancing

When a broker dies or a new one joins, whole partitions must be copied. The more data each broker holds, the longer that takes.

Retention

Short memory

Teams delete data early to save money, then discover later that they needed it for an audit, a bug investigation or a new machine learning model.

Workarounds

Copy jobs and extra pipelines

Many companies built connectors that copy Kafka data into a data lake. That works, but now there are two copies of the truth and one more system to run.

!
Key idea

Tiered storage does not make Kafka faster. It makes Kafka’s memory cheaper and its operations lighter, by letting storage grow without growing the fleet of brokers.

2Kafka Storage Basics You Need First

Tiered storage is built on top of how Kafka already stores data. If these building blocks are clear, everything that follows will feel natural.

Topics, partitions and offsets

A topic is a named stream of messages, like a channel called “orders” or “payments”. Because one machine cannot handle a busy topic alone, Kafka splits each topic into partitions. Each partition is an ordered list of messages that only ever grows at the end. Every message in a partition gets a number called its offset: 0, 1, 2, 3 and so on. A consumer remembers its offset the way you remember the page number in a book.

The log is a set of segment files

On disk, a partition is stored as a log. But the log is not one giant file. Kafka chops it into pieces called segments. At any moment only the newest segment, called the active segment, accepts new writes. When it gets too big or too old, Kafka rolls it: the active segment is closed and never changes again, and a fresh active segment is started. Closed segments are called inactive or rolled segments.

Analogy

Think of a diary written in a series of notebooks. You write only in the current notebook. When it is full you close it, put it on the shelf, and start a new one. You never go back and change a closed notebook. Tiered storage is going to move those closed notebooks to a warehouse.

What lives inside a segment

Each segment is really a small family of files that share a name based on the first offset they hold.

PartWhat it holdsWhy it exists
Log fileThe actual messages, one after anotherThis is the data itself
Offset indexA sparse map from offset to file positionLets Kafka jump close to any offset without scanning
Time indexA sparse map from timestamp to offsetLets consumers ask for “messages since 9 AM”
Transaction indexRecords of aborted transactionsLets readers skip messages from failed transactions
Producer snapshotState about producers that write idempotentlyPrevents duplicates after a restart
Leader epoch checkpointA history of which leader was in charge, and from which offsetKeeps replicas honest after leader changes

This list matters later, because tiered storage has to move all of these pieces, not just the messages. A segment without its indexes would be a book without a table of contents: still readable, but painfully slow to search.

Retention: how old data is removed

Kafka is not a database that keeps everything forever. Each topic has a retention rule, such as “keep seven days” or “keep 500 gigabytes per partition”. A background task deletes segments that break the rule. One detail trips up many newcomers: Kafka deletes whole segments, never single messages. A segment is only eligible once its newest message is older than the limit.

Replication: the reason for three copies

Each partition has one leader broker that handles all reads and writes, and one or more followers that copy the leader’s log. If the leader dies, a follower that is fully caught up takes over. The group of caught-up replicas is called the in-sync replica set, or ISR. This is what makes Kafka safe, and it is also what triples the disk you need.

Why Kafka reads are so fast

Kafka leans on the operating system’s page cache, a part of memory the OS uses to hold recently touched file data. A consumer that is close to the tail of the log usually reads straight from memory, never touching the disk. Keep this in mind. The difference between reading fresh data and reading old data is a central theme of tiered storage.

Why segments make tiering natural

Kafka’s habit of writing in straight lines and closing files when they fill up turns out to be the perfect starting point for tiering. A closed segment is a finished, unchangeable package. It can be copied without worrying that someone will edit it halfway through. It can be checked by comparing sizes. It can be read in slices because its index tells you exactly where each offset begins. And it can be deleted as a single unit. If Kafka rewrote old data in place, like a database updating a row, moving that data to another system would be far harder. The append-only log is what makes the whole idea possible.

There is one more useful fact. Each segment has a name based on the first offset it contains, so segments are already in a clear order. Kafka can tell which segment holds any offset just by comparing numbers. This same ordering is used later to name and find segments in the remote tier.

i
Remember

Only closed segments can be moved. The active segment is still being written to, so it always stays on the broker.

3What Tiered Storage Actually Is

The idea is simple to say and subtle to build: split each partition’s history across two kinds of storage and hide the split from applications.

Two tiers, one log

With tiered storage, a partition’s log has two homes. The local tier is the broker’s own disks, fast and expensive per gigabyte. The remote tier is an external storage system, slower and far cheaper per gigabyte, usually object storage such as Amazon S3, Google Cloud Storage or Azure Blob Storage. Recent segments are kept in the local tier. Older segments are copied to the remote tier and, after a while, deleted from the local disks.

The important point is that it is still one logical log. Offset 5 is offset 5 whether it sits on a local disk or in a bucket. A consumer asks for an offset and Kafka finds it, wherever it lives.

Analogy

A hospital keeps this week’s patient files at the nurses’ station and moves older files to a records building across town. A doctor asks the front desk for a file by patient number. The desk finds it in either place. Fetching from the records building takes longer, but the doctor never needs to know which building held it.

What does not change

Producers

No change

Producers still send messages to the partition leader. They never talk to object storage.

Consumers

No change

Consumers use the same fetch requests and the same offsets. Reading old data simply takes a bit longer.

Topics

Opt in per topic

You switch tiering on for the topics that benefit. Others keep working the old way.

Ordering

Same guarantees

Order within a partition, offsets and delivery semantics are all preserved.

A short history

The idea of separating hot and cold data is old in databases and file systems. In Kafka’s world, several vendors built their own private versions first. Confluent shipped tiered storage in its commercial platform and cloud service, and Amazon offered tiered storage on Amazon MSK for provisioned clusters. Other streaming systems took different routes: Apache Pulsar offloads old segments to object storage, and Redpanda has its own cloud storage feature built into the broker.

The open source community wanted a standard version. The design was written up as KIP-405 (a KIP is a Kafka Improvement Proposal). Engineers from several companies, including Uber and Confluent, refined it over several years. It reached early access in Apache Kafka 3.6 in late 2023, and was declared production ready in Apache Kafka 3.9 in late 2024.

MilestoneWhat it meant for users
Vendor implementationsConfluent and Amazon MSK offered private, product-specific tiering
KIP-405 acceptedA shared design with pluggable storage backends
Kafka 3.6Early access, good for testing but not for critical workloads
Kafka 3.9Declared production ready, with the ability to turn tiering off for a topic
!
Heads up

Open source Kafka defines the plumbing but does not ship a storage plugin for S3 or GCS. You bring a plugin, either from a vendor or from an open source project such as the ones published by Aiven, or you use a managed service that has it built in.

4Architecture and Core Components

Four moving parts make tiering work. Learn their names now and the rest of this guide will read like a story.

The four building blocks

ComponentJobEveryday comparison
Local logHolds the active segment and recent closed segments on broker disksThe nurses’ station
RemoteLogManagerThe coordinator inside every broker; schedules copying, cleaning and remote readsThe records clerk
RemoteStorageManager (RSM)A plugin that knows how to write, read and delete segment files in the chosen storage systemThe delivery truck to the records building
RemoteLogMetadataManager (RLMM)A plugin that keeps the catalogue of which segment lives whereThe card catalogue at the front desk
flowchart TB
    PR["Producers"] --> LL
    CO["Consumers"] --> LL
    subgraph LB["Leader Broker"]
        LL["Local Log: active and recent segments"]
        RLM["RemoteLogManager"]
        RSM["RemoteStorageManager plugin"]
        RLMM["RemoteLogMetadataManager plugin"]
        LL --> RLM
        RLM --> RSM
        RLM --> RLMM
    end
    LL --> FB["Follower Brokers: copy the local tier only"]
    RSM --> OBJ["Object Storage: S3, GCS, Azure Blob or HDFS"]
    RLMM --> MT["Internal topic: __remote_log_metadata"]
Figure 1. Where each component sits. Clients only ever talk to the broker; the plugins talk to the outside world.

Reading the diagram

Producers and consumers connect to the leader broker exactly as they always did. Inside the broker, the local log is the familiar set of segment files. Next to it sits the RemoteLogManager, a new piece of broker code that owns everything related to the remote tier. It does not know how to speak to Amazon S3 or Google Cloud Storage. Instead, it calls the RemoteStorageManager plugin, which does. Swapping storage systems means swapping the plugin, not rewriting Kafka.

The RemoteLogMetadataManager plugin answers a different question: “For partition 7 of the orders topic, which segments exist in remote storage, and what offsets does each cover?” The default implementation keeps this catalogue in an internal Kafka topic, so Kafka uses itself to remember where its own history went.

Why two plugins instead of one

Storing bytes and remembering where the bytes went are separate problems. Object stores are excellent at holding large files but poor at fast, consistent lookups across thousands of small records. Kafka topics are excellent at fast, ordered, replicated records. So the design lets each system do what it is best at. The bulk data goes to the bucket. The small catalogue stays in Kafka.

Who does the work

Only the leader of a partition copies its segments to the remote tier. Followers do not upload, which prevents three brokers from uploading the same segment three times. If leadership moves, the new leader picks up where the old one stopped, guided by the catalogue.

!
Design win

Because the storage backend is a plugin, the same Kafka feature can sit on top of a public cloud bucket, a private object store in your data centre, or a distributed file system such as HDFS.

5What a Storage Plugin Must Do

The RemoteStorageManager plugin is where Kafka meets the outside world. Understanding its job explains many of the behaviours you will see in production.

The four jobs

Kafka asks the plugin to do only four things. Everything else, such as deciding when to copy and what to keep, stays inside the broker. This small contract is what makes the design so portable.

OperationWhat the broker asksEveryday comparison
Copy segment“Store this closed segment and all its companion files”Sending a sealed box to the warehouse
Fetch segment range“Give me the bytes from position A to position B of that segment”Asking for chapter 5 of a stored book, not the whole book
Fetch index“Give me the offset index, time index or other companion file”Asking for the table of contents
Delete segment“Remove everything stored for that segment”Shredding the box and its contents list

Good plugins handle the boring details well

Naming

Careful object keys

Each object needs a unique name built from the topic’s unique ID, the partition and the offset range. Using the ID instead of the topic name avoids clashes if a topic is deleted and recreated with the same name.

Big files

Multipart uploads

Large segments are sent in parts, so a failure only forces a retry of one part, not of the entire file.

Reliability

Retries with backoff

Storage services occasionally return temporary errors. A good plugin retries politely and gives up cleanly so the broker can try again later.

Speed

Range reads and caching

Reading only the needed bytes and caching popular chunks cuts both latency and request bills.

Safety

Credentials and encryption

Using role-based identities and supporting encryption keeps secrets out of configuration files. Some plugins also offer extras such as compression or client-side encryption.

Visibility

Useful metrics

Counts of requests, errors and bytes for each operation help you spot trouble before users do.

Why the key layout matters

Object stores spread data across many machines by looking at the beginning of each object’s name. If every name starts the same way, requests can pile up on the same machines. Well-designed plugins add variety near the start of the key, so traffic spreads out. This is invisible when you are small and painful when you are large, so ask about it when choosing a plugin.

!
Tip

Before you choose a plugin, ask five questions. Which Kafka versions does it support? How does it name objects? How does it authenticate? Does it cache and retry? How active is its maintenance?

6How Data Moves to the Remote Tier

Copying happens quietly in the background. Producers and consumers never wait for it, and it never touches the active segment.

The copy loop

Every broker runs a pool of background threads that belong to the RemoteLogManager. For each partition where the broker is the leader, one task wakes up on a regular schedule (every 30 seconds by default) and asks a simple question: “Are there closed segments that have not been uploaded yet?” If the answer is yes, it starts uploading them, oldest first.

There is one safety rule. A segment is only uploaded when all of its messages are fully settled. That means the messages are replicated to the in-sync followers, and any transactions inside them have finished, either committed or aborted. Kafka tracks this using a marker called the last stable offset. Nothing beyond that marker is allowed to leave the broker. This stops half-finished transactions from being frozen into cold storage.

sequenceDiagram
    participant L as Leader Broker RemoteLogManager
    participant M as Metadata Manager
    participant S as Storage Plugin
    participant O as Object Storage
    L->>L: Find closed segments not yet copied
    L->>M: Record segment as COPY_SEGMENT_STARTED
    L->>S: Hand over segment, indexes and snapshots
    S->>O: Upload the files
    O-->>S: Upload acknowledged
    S-->>L: Copy complete
    L->>M: Record segment as COPY_SEGMENT_FINISHED
    Note over L: Local copy stays until local retention expires
Figure 2. The upload of one closed segment, step by step.

Walking through the steps

1

Find work

The leader lists its closed segments and compares them with the catalogue to see which are still local only.

2

Announce the plan

Before uploading a single byte, the leader writes a “copy started” record to the metadata topic. If it crashes mid-upload, everyone knows an unfinished upload exists.

3

Upload the whole family

The storage plugin sends the message file, the offset and time indexes, the transaction index, the producer snapshot and the leader epoch history.

4

Confirm

Once the storage system acknowledges the upload, the leader writes “copy finished”. Only now does the segment count as safely tiered.

5

Wait for local retention

The local copy is not deleted immediately. It is kept until the local retention rule says it is old enough.

What if the upload fails?

Networks fail and buckets have bad days. If an upload does not complete, the segment is simply tried again on the next cycle. The catalogue still says “started”, not “finished”, so no reader is ever pointed at a half-uploaded segment. Leftover partial files are cleaned up later. This is the same idea a careful shipping company uses: the package is not marked as delivered until the receiver signs for it.

Why segment size matters so much

Only closed segments are copied, and a segment closes when it reaches its size limit (1 gibibyte by default) or its age limit (7 days by default), whichever comes first. This has a surprising effect on quiet topics. A topic that receives only a trickle of data may take days to fill a segment, so its data stays on local disks longer than you might expect.

!
Tip

For low-traffic topics, lower the segment age limit so that segments roll more often and reach the remote tier sooner. For very busy topics, make sure segments are not so small that you create millions of tiny objects in the bucket.

The cost of copying

Uploading is not free. Every tiered byte must be read from the broker’s disk (or page cache) and pushed over the network to the storage system. On a busy cluster this adds steady background traffic on top of normal replication. Recent Kafka versions include throttles that cap how fast a broker may copy and how fast it may read back, so tiering cannot starve real-time traffic. Plan for this extra network load when you size your brokers.

7The Life of a Segment

A segment passes through clear stages from birth to deletion. Knowing them helps you read metrics, predict disk usage and debug problems.

stateDiagram-v2
    [*] --> Active
    Active --> Rolled: segment rolls
    Rolled --> Copying: leader starts upload
    Copying --> Rolled: upload fails, retry later
    Copying --> Tiered: upload finished
    Tiered --> RemoteOnly: local retention expires
    Tiered --> Deleting: total retention expires
    RemoteOnly --> Deleting: total retention expires
    Deleting --> [*]: files removed from remote storage
Figure 3. The stages a segment moves through.

Stage by stage

StageWhere the data livesWhat is happening
ActiveLocal disk onlyReceiving new messages from producers
RolledLocal disk onlyClosed and waiting for the next copy cycle
CopyingLocal disk, partly remoteUpload in progress; not yet trusted by readers
TieredLocal disk and remote storageSafe in both places; readers may use either
RemoteOnlyRemote storage onlyLocal copy deleted; reads go through the remote path
DeletingRemote storage, being removedTotal retention expired; cleanup running

Two start markers you should know

Kafka tracks two numbers for each partition. The log start offset is the very first offset that still exists anywhere, local or remote. It moves forward only when total retention deletes old data. The local log start offset is the first offset still on the broker’s own disks. It moves forward whenever local retention removes a segment that has already been tiered. The gap between the two numbers is exactly the amount of history that lives only in remote storage.

A worked example

A partition holds offsets 0 to 9,999,999. The remote tier has everything from offset 0 up to 8,999,999. The local disk holds 9,000,000 onward. Here the log start offset is 0 and the local log start offset is 9,000,000. A consumer asking for offset 4,500,000 is served from remote storage. A consumer asking for 9,500,000 is served locally.

The safety guarantee behind local deletion

Kafka will never delete a local segment that has not been confirmed as copied. This single rule protects you from data loss. It also has a flip side that we will meet again in the mistakes chapter: if copying stalls, local disks cannot be cleaned, and they slowly fill up.

Metadata states

The catalogue records four states for every remote segment: copy started, copy finished, delete started and delete finished. The two “delete” states mirror the two “copy” states for the same reason. If a broker crashes halfway through cleanup, the catalogue shows that deletion was in progress, and a later run can safely finish the job.

8How Reads Work

A consumer sends the same fetch request as always. The broker quietly decides whether to answer from the counter or from the storeroom.

flowchart TD
    A["Consumer sends a fetch request with an offset"] --> B{"Is the offset in the local log?"}
    B -->|"Yes"| C["Read from page cache or local disk"]
    B -->|"No, it is older than the local log start"| D["Ask the metadata manager which remote segment holds it"]
    D --> E["Remote reader thread fetches the needed bytes through the storage plugin"]
    E --> F["Broker returns the data to the consumer"]
    C --> F
Figure 4. The decision every fetch request goes through.

The local path

If the requested offset is at or after the local log start offset, nothing is different from classic Kafka. The broker looks up the position in the offset index, reads the bytes and returns them. Real-time consumers, which stay close to the tail of the log, live here. They see the same speed as before.

The remote path

If the offset is older than anything on local disk, the broker asks the metadata manager: “Which remote segment covers this offset?” It then asks the storage plugin for just the part it needs. Object stores allow reading a byte range from inside a large object, so the broker does not download a whole 1 gibibyte segment to serve a small fetch. It first reads the small index files to find the right position, then reads the exact range of messages.

Crucially, this work does not happen on the broker’s main network threads. Slow remote reads are handed to a separate pool of remote reader threads, and the fetch request waits in a holding area until the data arrives. This keeps a slow bucket from freezing the broker’s normal traffic.

Analogy

A librarian at the front desk can hand you a book from the shelf behind her instantly. If you ask for an old book stored in the basement, she does not walk away and leave the desk unattended. She sends a helper to fetch it and keeps serving other visitors until the helper returns.

Speed expectations

Local reads from memory take well under a millisecond. Remote reads must cross a network to an object store, and the first byte typically arrives after tens of milliseconds. That is fine for a job replaying last month’s data, but it would be a poor fit for a service that needs an answer within five milliseconds. Once the first bytes arrive, however, remote throughput can be very high, especially when many partitions are read in parallel, because object stores scale out well.

Under 1 ms
typical local read served from page cache
Tens of ms
typical time to first byte from object storage
Unchanged
consumer API, offsets and ordering

A hidden benefit: protecting the page cache

In classic Kafka, when a consumer replays old data, the broker must read old segments from disk. Those reads pull cold data into the page cache and push out the hot data that real-time consumers need. The result is a “noisy neighbour” problem: one big replay job can slow everyone else. With tiered storage, old data is served through the remote path instead of the local disk, which reduces this interference.

Indexes are cached

Reading the same small index files from the bucket again and again would be wasteful. The broker keeps a local cache of recently used remote index files, with a configurable total size. This is a small cache, but it makes repeated reads from the same remote segment far faster.

i
Real-world note

Uber, which runs one of the largest Kafka deployments in the world, has publicly discussed tiered storage as a way to keep data longer without buying brokers in proportion to the amount of history kept.

9The Journey of One Message

Let us follow a single order event through its entire life in a tiered cluster. This ties every earlier chapter together.

Imagine an online shop sends an event called “order 84213 placed” to a topic named orders. The topic keeps data for 30 days in total and one day on the brokers. Here is what happens.

1

Second 0: the write

The producer sends the event to the leader of the partition chosen for it. The leader appends it to the active segment and assigns it an offset.

2

Milliseconds later: replication

Followers fetch the new message and copy it into their own active segments. Once enough replicas have it, the message becomes visible to consumers and the producer receives its acknowledgment.

3

Seconds later: first reads

The shipping service, tailing the log, reads the event straight from memory. Nothing about tiering is involved.

4

Hours later: the segment closes

The active segment reaches its size limit and rolls. The event is now inside a closed segment, and no more writes will ever touch it.

5

Within a minute or so: the upload

The next copy cycle on the leader uploads the segment with its indexes. The catalogue records “copy finished”. The event now exists on local disks and in the bucket.

6

Day 1: local cleanup

Local retention expires. Each broker deletes its local copy of the segment, and the local log start offset moves forward past the event.

7

Day 10: a replay

A data scientist starts a job that reads the topic from the beginning. When it reaches offset of the event, the broker fetches it from the bucket through the remote path.

8

Day 31: the end

Total retention expires. The leader marks the segment for deletion, removes its files from the bucket, and the log start offset moves forward. The event is gone.

What this story shows

The event was written once, replicated locally for a short time, copied once into the bucket, and deleted twice: once from the brokers and once from the bucket. Its offset never changed. The application that replayed it on day 10 used the same client library as the shipping service on second 3. The complexity lives inside the broker, which is exactly where it should live.

i
Think about it

Between step 4 and step 5 the event exists only in a closed local segment on three brokers. Between step 5 and step 6 it exists in four places. After step 6, the bucket holds the only copies. This is why bucket protection matters so much.

10Retention Rules Explained

With two tiers you need two clocks. Getting these settings right is the difference between a smooth rollout and a full disk at 3 AM.

Two kinds of retention

The familiar retention.ms and retention.bytes settings now describe the total lifetime of the data, across both tiers. Two new settings, local.retention.ms and local.retention.bytes, describe how long data stays on the broker’s own disks. By default the local settings follow the total settings, which means no data would leave the broker early. You must lower the local values to see any benefit.

SettingControlsExample
retention.msTotal age limit across local and remote tiers30 days
retention.bytesTotal size limit per partition across both tiersUnlimited
local.retention.msAge limit on broker disks1 day
local.retention.bytesSize limit per partition on broker disksUnlimited

A timeline for one segment

Age of the segmentLocal diskRemote storage
Just closedYesNot yet
A few minutes oldYesYes, after the next copy cycle
2 days oldNo, local limit of 1 day passedYes
31 days oldNoNo, total limit of 30 days passed

Infinite retention

Setting total retention to unlimited turns Kafka into a long-term record of everything that ever happened. This is powerful for event sourcing, audit trails and replaying history into new systems. Before tiering, it was too costly for most teams. With object storage, keeping years of data can cost less than a single extra broker.

Rules that must hold

  • Local retention should never be larger than total retention. It would make no sense to keep data locally that is already deleted overall.
  • Tiering is switched on per topic. Enabling it on a topic that already has data means existing closed segments are copied over time, not instantly.
  • Deleting a topic also removes its data from remote storage, so treat topic deletion with the same care as before.
!
Warning

Setting local retention very low is tempting because it saves the most disk. But local disks can only shrink after segments are copied. If your copy speed is lower than your write speed, or if the bucket has an outage, local disks fill up because nothing can be deleted safely. Always leave generous headroom.

Choosing the local window

A helpful rule of thumb is to keep on local disks whatever your normal, latency-sensitive consumers read. If all your real-time consumers stay within an hour of the tail, a local window of several hours to a day gives comfortable room for consumer restarts and small outages. Anything older is a replay, and replays can tolerate the remote path.

11Replication, Leader Changes and Recovery

This is where tiered storage quietly pays off the most. Operations that used to take a day can shrink to an hour.

Followers copy only the local tier

The remote tier already stores each segment once, inside a storage system that keeps its own extra copies for safety. So Kafka does not ask three brokers to each hold a full local copy of the old history. Followers replicate only what is on the leader’s local disks. The leader’s local log start offset tells a follower where to begin.

Think about what happens when a broker dies and a replacement joins. In classic Kafka, the newcomer must copy every partition it now owns, from the very first offset to the last. With tiering, it starts from the leader’s local log start offset and copies only the recent window. The older history stays in the bucket where it always was. The newcomer also downloads a few small pieces of state, such as the leader epoch history and producer snapshots, so it can behave correctly.

About 28 hours
to copy 20 TB to a new broker at 200 MB per second
About 1.4 hours
to copy 1 TB of local data at the same speed
Same data
still readable by consumers throughout
Analogy

When a new librarian joins a branch, she only needs to learn the shelves at the front of the building. She does not need to memorise the entire warehouse. Anyone who wants an old book can still get it from the warehouse.

Leader elections

If the leader fails, a caught-up follower is elected as the new leader, just as before. The new leader does not have to rebuild anything for the remote tier. It reads the catalogue, sees which segments are already uploaded, and continues copying from the next one. The catalogue records the leader epoch for every remote segment. A leader epoch is a counter that goes up each time a new leader is chosen, and it acts like a version number for the log’s history. Using it, Kafka can tell which remote segments belong to the current history and which came from an older history that was cut off by a leader change.

Failure scenarios

What failsWhat still worksWhat suffers
One broker crashesEverything, after leader electionRecovery copies only the local window, so it is quick
Object storage is unreachableProducing and reading recent dataReads of old data fail; uploads pause; local disks start filling
Metadata topic is unhealthyProducing and reading recent dataRemote reads and uploads cannot find or record segments
Upload crashes midwayEverythingThe half-finished segment is retried and cleaned up later
Bucket data deleted by mistakeRecent data still on local disksOlder history is lost; Kafka cannot rebuild it
!
Important

Once old data is deleted locally, the bucket is the only home of that history. Protect it as you would a database: restrict who can delete objects, and consider versioning or object lock features offered by your storage provider.

Rebalancing and scaling out

Adding a broker to spread the load used to be a painful, hours-long event. Now the amount of data that must move is small, so scale-out becomes a routine task. Likewise, replacing a failed disk or an ageing machine no longer feels like an emergency. This is often the strongest argument for tiering on busy production clusters, even for teams that do not care about long retention.

12Guarantees: Ordering, Durability and Availability

A storage feature is only trustworthy if you know exactly which promises it keeps. Here are the promises that survive tiering, and the ones that change shape.

Promises that stay the same

PromiseWhat it meansEffect of tiering
Ordering in a partitionMessages are read in the order they were writtenUnchanged; offsets are the same in both tiers
Stable offsetsA given offset always refers to the same messageUnchanged; moving a segment does not renumber it
Committed data is not lostA message acknowledged by the required replicas survives a broker failureUnchanged for recent data
Transactional visibilityReaders see only committed transactions if they ask for thatUnchanged; indexes travel with segments
Delivery semanticsAt-least-once or exactly-once, depending on your setupUnchanged

How durability changes

Before tiering, durability of a message came from three broker disks holding copies. With tiering, old data gains a second kind of durability. Once a segment is uploaded, its safety rests on the storage system, which is designed for extreme durability. Amazon S3, for example, is designed for eleven nines of durability, meaning the chance of losing a given object in a year is astronomically small. This is often better than three local disks.

But there is a subtle point. Durability now depends on two different systems, and their protections are configured differently. The brokers protect recent data with replication. The bucket protects old data with its own internal copies. Neither protects you from someone deleting things by mistake. That is why access control and deletion safeguards for the bucket are part of your durability plan, not just your security plan.

How availability changes

The cluster is now available for old data only if both Kafka and the storage system are available. It is available for recent data even when the storage system is down. In other words, the tiering feature adds a dependency for one kind of read, but not for the core work of accepting and serving fresh messages. This partial independence is a deliberate design choice: the bucket being slow or unreachable should hurt replay jobs, not the live business.

Analogy

A hospital’s emergency room keeps working even if the records building across town loses power. Doctors can still treat new patients using the files at the nurses’ station. Only requests for old records have to wait.

What happens on unclean leader elections

Sometimes every up-to-date replica is lost and Kafka is configured to allow a behind replica to become leader anyway. This is called an unclean leader election, and it can drop the newest messages. With tiering, the leader epoch history stored with remote segments helps Kafka keep the two tiers consistent. Segments written under a history that got cut off are not served as if they belonged to the new history. The rules for what is lost do not become worse, but the extra bookkeeping is one more reason the catalogue must be kept healthy.

Consistency between tiers

A reader who asks for offset 100 gets the same message whether it comes from local disk or remote storage, because both copies were made from the same closed, unchangeable segment. The copy is only trusted after the catalogue records it as finished. There is no time when two readers can see two different versions of the same offset.

!
Design principle

Immutability makes all of this work. A closed segment never changes, so copying it, caching it, reading it in pieces and deleting it are all simple, safe operations.

13The Remote Metadata Layer

The catalogue is the brain of tiered storage. If the bucket holds the books, the catalogue knows which shelf each book is on.

What the catalogue must answer

QuestionWhy it matters
Which remote segments exist for this partition?Needed to compute how much history is available
Which segment holds offset N?Needed for every remote read
Which leader epoch wrote this segment?Needed to keep history consistent after leader changes
Is this segment complete, or half uploaded?Needed so readers never touch incomplete objects
Which segments have passed total retention?Needed to delete them from the bucket

The default: a Kafka topic

Kafka ships with a catalogue implementation that stores its records in an internal topic named __remote_log_metadata. Each event, such as “copy started” or “delete finished”, is one message in that topic. Every broker reads the topic and builds an in-memory picture of the segments it cares about. Because the topic is an ordinary replicated Kafka topic, it inherits Kafka’s durability and ordering for free.

The internal topic has its own number of partitions and its own replication factor, both configurable. Different user partitions map to different metadata partitions, which spreads the catalogue’s load. The metadata topic itself is not tiered, and its records are kept indefinitely so the catalogue never forgets a segment that still exists.

Analogy

Kafka keeps a diary about where it filed its old diaries. It is a little like asking a bank to keep a ledger of which safety deposit boxes exist. The ledger is small, but without it the boxes are useless.

What happens at broker start-up

When a broker restarts, it must read the metadata topic to rebuild its picture. For clusters with an enormous number of tiered segments, this takes time, and remote reads for a partition wait until the broker has caught up on that partition’s metadata. This is one more reason not to create absurd numbers of tiny segments.

Consistency and object stores

Older object stores were only “eventually consistent”, meaning a freshly uploaded file might not be visible right away. This used to make designs like this risky. Modern services such as Amazon S3 now give strong read-after-write consistency, so once an upload is confirmed, it can be read. Even so, Kafka does not rely on this alone. Reads are only pointed at segments the catalogue marks as finished, which adds a second layer of safety.

Custom catalogues

The metadata manager is also a plugin. A company could replace the default with a catalogue stored in a database or in the object store itself. Most teams keep the default because it needs no extra infrastructure.

!
Tip

Monitor the metadata topic like any other critical topic: check its under-replicated partitions and consumer lag. If the catalogue is unhealthy, tiering is unhealthy.

14How Tiering Works With Other Kafka Features

Kafka is more than a log. Transactions, consumer groups, stream processing and mirroring all touch stored data, so it helps to know how each behaves when history is split across two tiers.

Transactions and exactly-once processing

A transaction lets a producer write to several partitions and have them all become visible together, or not at all. Consumers configured to read only committed data must skip messages from transactions that were aborted. To do that, Kafka keeps a small transaction index next to each segment. Tiered storage uploads this index along with the segment, so a consumer reading old data through the remote path still skips aborted messages correctly. The rule that only stable data may be uploaded exists for exactly this reason: a transaction still in progress could otherwise be frozen in an unknown state.

Idempotent producers

An idempotent producer is one that Kafka protects from writing duplicates, even when it retries after a network error. The broker remembers the latest sequence numbers per producer in a producer snapshot file. As you saw earlier, that snapshot is part of the family of files uploaded with each segment. When a new broker takes over, it restores the snapshot so duplicate protection keeps working.

Consumer groups and committed offsets

Consumer groups remember their progress by saving offsets into an internal topic. That internal topic is small and compacted, and it is not tiered. Your committed offsets therefore work exactly as before. If a group has been down for two weeks and resumes, its saved offset simply points into the remote tier, and the group catches up through the remote read path without any special action.

Looking up messages by time

Applications often ask, “Give me the first message after 3 PM last Tuesday.” Kafka answers this using the time index. With tiering, the time index of remote segments is stored in the bucket, so these lookups work across both tiers. The lookup may take a little longer when it has to fetch a small index file from remote storage, but the result is the same.

Kafka Streams, Kafka Connect and mirroring

Streams

State rebuilds

Stream processing applications rebuild their local state from changelog topics. Those are usually compacted, so they stay on brokers. Input topics that are tiered can be reprocessed from the start after a bug fix.

Connect

Reloading sinks

A sink connector that feeds a database or search index can be pointed at the beginning of a tiered topic to rebuild the target from scratch.

Mirroring

Cross-cluster copies

Tools that mirror topics between clusters read like ordinary consumers. Starting a new mirror from the earliest offset now reads history through the remote path.

Quotas

Same limits apply

Remote reads still pass through the broker, so client bandwidth quotas continue to govern how fast any one application may read.

Topics that cannot be tiered

Two kinds of topics stay on broker disks. Compacted topics are excluded because compaction rewrites segments. Kafka’s own internal topics, such as those that store consumer offsets and transaction state, are excluded too, because they are compacted and small. This is a good design: the data that needs constant rewriting stays close to the brokers, while the large, append-only event streams are the ones that move.

i
Good to know

Nothing about your consumer code needs to change to work with tiered data. What changes is timing. Design batch jobs and rebuild jobs to expect slower first reads, and set client timeouts with that in mind.

15Turning It On: A Configuration Guide

Enabling tiering is a small number of switches, but the order and the values matter. Here is the path in plain steps.

1

Pick a storage plugin

Choose a plugin for your storage system and place it where every broker can load it. Confirm that it matches your Kafka version.

2

Prepare the bucket and permissions

Create a bucket in the same region as your brokers. Give the brokers an identity, ideally through a role rather than a fixed password, with just enough permission to read, write and delete objects under one prefix.

3

Switch it on for the cluster

Set the broker-level flag that enables the remote log storage system, name the storage plugin class, and pass the plugin its own settings. This needs a rolling restart of the brokers.

4

Choose topics

Enable remote storage on the topics that benefit: high-volume topics with long retention are the best candidates.

5

Set the two clocks

Set total retention for the topic and a shorter local retention so old segments can leave the disks.

6

Test before trusting

Start with a non-critical topic. Produce data, wait for segments to be tiered, then read from the beginning and confirm the data is complete.

The settings that matter most

SettingLevelPurpose
remote.log.storage.system.enableBrokerMaster switch for the feature on the cluster
remote.storage.enableTopicTurns tiering on for one topic
local.retention.ms and local.retention.bytesTopicHow long or how much data stays on broker disks
segment.bytes and segment.msTopicHow quickly segments close and become eligible for copying
remote.log.manager.task.interval.msBrokerHow often the copy and cleanup tasks run (30 seconds by default)
remote.log.reader.threadsBrokerSize of the pool that serves remote reads (10 by default)
remote.log.index.file.cache.total.size.bytesBrokerSize of the local cache for remote index files (1 GiB by default)

Sizing segments sensibly

Segment size is the most underrated knob. Too large and quiet topics take ages to tier and local disks stay full. Too small and you create huge numbers of tiny objects, which slows the catalogue, multiplies storage requests and increases cost. Many teams settle on segments of a few hundred megabytes to one gibibyte for busy topics, and use an age limit to force rolls on quiet ones.

Turning it off

Before Kafka 3.9, tiering could not be safely switched off once enabled. From 3.9 onward it can be disabled on a topic, and you choose whether the remote data is deleted or left in place. Because this is a big decision, treat enabling tiering as a commitment and test the exit route in a staging environment.

i
Good to know

Exact setting names and defaults change between Kafka versions. Always check the documentation for the version you run before copying values from any guide, including this one.

16Performance and Scalability Trade-offs

Tiered storage is not a free lunch. It trades a little speed for a lot of savings, and it moves some bottlenecks to new places.

Different readers, different experiences

Reader typeWhere it readsWhat changes
Real-time consumer near the tailPage cache and local diskNothing; it still sees the same low latency
Consumer restarting after a short outageUsually local diskNothing, if the local window is long enough
Consumer catching up after a long outageMostly remote storageSlower start, then high throughput
Analytics job replaying weeks of dataRemote storageHigher latency per fetch, but no impact on local disks
New service bootstrapping its stateRemote storageCan now read months of history without a special data lake copy

Where the new bottlenecks appear

Network

Extra traffic

Every tiered byte crosses the network to the bucket, and every remote read crosses it back. Plan broker network capacity for this.

Requests

Storage request limits

Object stores charge and limit by number of requests. Many small fetches from many partitions can hit those limits.

Threads

Reader pool size

If many consumers replay at once, the remote reader thread pool can become a queue.

Metadata

Catalogue growth

Long retention means more segments, which means more catalogue records to hold in memory.

Scalability in two directions

Before tiering, if you wanted twice the history you needed roughly twice the disks. Now history grows in the bucket, which has effectively no ceiling, while the number of brokers depends on throughput: how many megabytes per second you write and read. This separation of storage from compute is the deepest benefit of the feature. It lets you size each resource for what it actually does.

Storage should grow with your history. Compute should grow with your traffic. Tiering finally lets them grow separately.

Keeping replays from hurting real-time traffic

A well-run cluster puts limits around the remote path. Throttle how fast brokers copy and how fast they serve remote reads, so that a giant replay cannot eat all the network. Client quotas add another layer: they can cap how much bandwidth any one application may use. The goal is to make sure a batch job stays a polite guest.

Tuning consumers that read remote data

Because the first byte from object storage takes longer to arrive, consumers that replay old data should ask for more each time they fetch. Every fetch request pays a fixed waiting cost, so a small fetch wastes most of its time waiting. Raising the maximum bytes per fetch and per partition lets each round trip carry a much larger batch, which spreads that waiting cost across more messages.

Parallelism helps too. A topic with many partitions can be read by many consumer instances in the same group at once, up to one instance per partition. Since each instance issues its own remote reads, throughput scales almost in a straight line until you reach a limit in the network, the reader thread pool or the storage service. Finally, review client timeouts. A replay job that gives up after a few hundred milliseconds will fail needlessly, so give remote fetches a generous allowance.

Consumer setting ideaFor live consumersFor replay jobs
Fetch size per requestModerate; favours low latencyLarge; favours throughput
Number of instancesAs needed for the workloadUp to the partition count
Request timeoutShortLonger, to allow for remote reads
Client identity for quotasNormal applicationSeparate identity with its own limit
!
Tip

Run a realistic test. Replay a large topic from the beginning while producers and real-time consumers run at normal load, and watch latency. Numbers from your own workload are worth more than any rule of thumb.

17Capacity Planning Step by Step

Three resources need sizing: broker disks, network, and remote storage. Let us reuse the earlier scenario of 2 terabytes per day and work through each.

Step 1: turn daily volume into a rate

Two terabytes per day is about 23 megabytes per second on average (2,000,000 megabytes divided by 86,400 seconds). Traffic is rarely flat. Real systems see peaks of three to five times the average, so design for that peak, not the average.

Step 2: size the local disks

Local disk equals daily volume, times days kept locally, times the replication factor, plus headroom. With one day local and three copies, that is 6 terabytes. Keeping about 30 percent free for growth, uneven partitions and recovery brings it to roughly 8 terabytes across the whole cluster. Compare that with about 180 terabytes without tiering.

Step 3: size the network

Each byte crosses the network several times. Suppose three separate consumer groups read every message.

Traffic typeMultiplierAverage rate
Producers writing to leaders1xAbout 23 MB/s
Replication to two followers2xAbout 46 MB/s
Three consumer groups reading3xAbout 69 MB/s
Uploads to the remote tier1xAbout 23 MB/s
Total across the cluster7xAbout 161 MB/s

Tiering adds one more multiple of the ingest rate for uploads. Replays of old data add remote reads on top, and those can be large if many jobs run together. Spread the total across your brokers and check each broker’s network card with a comfortable margin.

Step 4: size the remote storage and the catalogue

Remote storage equals daily volume times total retention, which is 60 terabytes here, before any compression. If segments are up to 1 gibibyte, you will have at least sixty thousand segments to track. In practice more, because many partitions close segments earlier than the size limit. Keep an eye on the catalogue’s memory use as this number grows.

Step 5: size the thread pools

Copy and cleanup threads should be enough for uploads to keep ahead of closing segments. Remote reader threads should match how many replays you expect at once. Start with the defaults, watch the queue behaviour, and adjust.

8 TB
local disk needed, versus about 180 TB in classic Kafka
7x
total network multiple of the ingest rate in this example
60 TB
remote storage for 30 days of retention
!
Do not forget

Tiering shrinks the disk requirement but does not shrink the network requirement. It slightly increases it. If your brokers are already network-bound, tiering will not fix that.

18The Cost Model: A Worked Example

Numbers make the idea concrete. Here is a simple, honest calculation you can adapt to your own cluster.

The scenario

A company ingests 2 terabytes of new data per day into Kafka and wants to keep 30 days of history. Replication factor is 3. To keep things simple we assume block storage on the brokers costs about $0.08 per gigabyte per month and object storage costs about $0.023 per gigabyte per month. These are rounded, illustrative list prices. Real prices vary by provider, region and volume, and they change over time.

Without tiered storage

Thirty days at 2 terabytes per day is 60 terabytes of unique data. Three copies mean 180 terabytes of broker disk, or 180,000 gigabytes. At $0.08 that is about $14,400 per month for disks alone. And this ignores the free space real clusters must keep, which pushes the number higher.

With tiered storage

Keep one day on the brokers: 2 terabytes times 3 copies is 6 terabytes, or 6,000 gigabytes, costing about $480. The remote tier holds all 30 days once, which is 60 terabytes, or 60,000 gigabytes, costing about $1,380. The total is roughly $1,860 per month.

$14,400
monthly storage cost, classic Kafka disks only
$1,860
monthly storage cost with a one-day local window
About 87%
storage saving in this example
ItemClassic KafkaWith tiering
Data kept on brokers180 TB (60 TB x 3 copies)6 TB (2 TB x 3 copies)
Data kept in object storage0 TB60 TB (stored once)
Broker disk costAbout $14,400About $480
Object storage cost$0About $1,380
Total storageAbout $14,400About $1,860

Costs that appear on the other side

  • Request charges. Uploads and downloads are billed per request. With segments around 1 gibibyte, a few thousand uploads a day is tiny. Heavy replays that make millions of small reads are where request charges grow.
  • Data transfer. Traffic inside a region to object storage is usually free or cheap, but crossing regions or leaving the cloud is not. Keep the bucket next to the brokers, and use private network endpoints so traffic does not pass through expensive gateways.
  • Extra network load on brokers. You may need slightly stronger network capacity, but this is small compared with the disk you no longer need.
  • Fewer brokers. The bigger saving often comes from shrinking the fleet. If brokers were added only for disk, many can go away, saving compute costs as well.
!
Be honest with your numbers

Savings depend on how long you keep data compared with how much you keep locally. A cluster that only keeps a day or two of data has little to gain from the storage side. The gains come from long retention, or from the operational relief of faster scaling.

19Security, Monitoring and Operations

Moving data out of the brokers moves your security responsibilities too. The bucket is now part of your Kafka system.

Security: protect the bucket like a broker

Kafka access control lists protect topics on the brokers. They do not protect files in a bucket. Anyone who can read the objects can read the messages inside, because segments hold messages in Kafka’s ordinary format. So the bucket must be locked down as tightly as the brokers themselves.

Identity

Least privilege

Give brokers a role that can read, write and delete only under their own prefix. Do not use broad administrator rights.

In transit

Encrypted connections

Storage plugins should talk to the bucket over encrypted connections, ideally over a private network path.

At rest

Server-side encryption

Turn on encryption for the bucket, and use managed keys with audit logs when your rules require it.

Exposure

No public access

Block public access on the bucket at the account level, and review bucket policies regularly.

Protection

Guard against deletion

Restrict who may delete objects by hand. Versioning or retention locks can rescue you from mistakes.

Compliance

Erasure and residency

Segments cannot be edited, so deleting one person’s data on request means waiting for retention. Plan around this, and keep the bucket in the right region.

Choosing the network path to the bucket

The route that bytes take to reach the bucket affects both safety and cost. If brokers reach the storage service over the public internet, traffic leaves your private network and may be exposed to more risk. If it travels through a shared gateway that charges by the gigabyte, a busy tiering setup can create a surprising bill. Most cloud providers offer a private endpoint, which connects your network to the storage service directly, keeps traffic off the public internet and avoids the gateway charges. Using it is usually the right default. Also confirm that brokers in every availability zone can reach the endpoint, or a zone failure could take tiering down with it.

What to monitor

Kafka exposes new broker metrics for the remote tier. Names differ across versions, but they cover the same ideas: bytes copied per second, bytes fetched from remote per second, request rates, error counts for copy, fetch and delete, and the total size of the remote log. Recent versions also report how far behind the copy process is.

SignalWhy it mattersWorry when
Copy lagShows how far uploads trail behind closed segmentsIt grows steadily
Copy and delete errorsShow storage or permission problemsAny sustained non-zero rate
Remote fetch latencyShows the health of the read pathIt jumps well above your normal baseline
Remote reader thread usageShows whether replays are queuingThreads are saturated for long periods
Local disk usageShows whether cleanup is workingIt climbs while local retention should be deleting
Metadata topic healthThe catalogue must be availableUnder-replicated partitions or consumer lag
Bucket size and request costsShows trends in costGrowth beyond what retention predicts

Logging

Broker logs record what the RemoteLogManager and the storage plugin are doing. Upload failures, permission errors and timeouts appear here first. Make sure these logs are shipped to your central logging system and that you have alerts on repeated errors.

Operating routines

  • Test restoring a broker from scratch while tiering is on, and time it.
  • Practise a bucket outage in staging so the team knows what a full local disk looks like.
  • Upgrade brokers and plugins together, and read release notes for tiered storage changes.
  • Do not add bucket lifecycle rules that delete or archive Kafka’s objects. Kafka manages deletion itself, and outside interference breaks the catalogue’s promises.

20Troubleshooting Guide

When something looks wrong, start with the symptom. This table covers the problems teams meet most often.

SymptomLikely causeWhat to check
Local disks keep fillingUploads are failing or slow, or local retention is too generousCopy errors, copy lag, storage permissions, local retention values
Tiering cannot be enabled on a topicCluster flag is off, plugin did not load, or the topic is compactedBroker startup logs, topic cleanup policy, broker version
Old-data reads time outStorage latency, too few reader threads, or bucket in the wrong regionRemote fetch latency, thread usage, network path to the bucket
Replays slow down live consumersNo throttles, or network saturationQuotas, network usage per broker, remote fetch rates
Permission denied errorsRole lacks rights, or bucket policy blocks the brokerIdentity in use, bucket policy, key management rights
Huge number of small objectsSegments roll far too oftenSegment size and age settings, partition count
Slow broker restartsLarge metadata topic to replayNumber of remote segments, metadata topic size
Unexpected storage billHeavy replays, cross-region traffic, or tiny objectsRequest counts, data transfer reports, segment size
Remote data missing after a changeManual deletion or a bucket lifecycle ruleBucket audit logs and lifecycle configuration

A calm way to investigate

1

Decide which path is sick

Is it the copy path, the read path, the cleanup path, or the catalogue? The metrics are grouped that way for a reason.

2

Check the storage first

Most problems are permissions, network paths or storage service limits, not Kafka bugs.

3

Look at one partition

Pick a single affected partition and follow it: its local start offset, its remote segments and its errors.

4

Change one thing at a time

Adjust a single setting, wait through at least one copy cycle, and observe the result before changing more.

21Limitations, Anti-patterns and Common Mistakes

Every useful feature has edges. Knowing them in advance saves painful surprises.

Built-in limitations

Works well for

  • Topics that keep data for a long time
  • High-volume topics where disk dominates the bill
  • Clusters where scaling and recovery are slow
  • Replaying history into new systems

Not a fit for

  • Compacted topics, which keep the latest value per key, are not supported
  • Workloads that need every read to be under a few milliseconds
  • Very small clusters with short retention
  • Environments with no reliable object storage nearby

Compaction rewrites old segments to remove outdated values. That does not fit with immutable, already-uploaded segments, which is why compacted topics are excluded. Also remember that early releases had gaps, so check the notes for your version before relying on a feature.

Common mistakes

Mistake 1

Enabling it everywhere

Tiering adds moving parts. Start with the few topics that dominate your storage.

Mistake 2

Forgetting the local setting

Leaving local retention at its default means nothing ever leaves the brokers and there are no savings.

Mistake 3

Tiny segments

Millions of tiny objects slow the catalogue and inflate request bills.

Mistake 4

Bucket in the wrong place

A bucket in a distant region adds latency and transfer charges.

Mistake 5

Ignoring quotas

Without throttles, one replay can crowd out normal traffic.

Mistake 6

Never testing an outage

The first time you see a bucket failure should not be in production.

ANTI-PATTERN 01Avoid
Context

A team wants the biggest possible saving, so it sets local retention to just a few minutes on every topic.

What goes wrong

Segments only close every few hours, and they can only be removed after they are uploaded. Real-time consumers that lag by even a short time now fall onto the slower remote path. During a storage outage, uploads stall and disks fill, because the safe cleanup rule blocks deletion.

Better approach

Set the local window to cover what normal consumers read, plus generous room for restarts and outages. Then measure disk usage and adjust slowly.

A short checklist before go-live

  • Have you confirmed the plugin supports your exact Kafka version?
  • Have you chosen local retention using real consumer behaviour?
  • Are throttles and quotas set?
  • Do alerts exist for copy lag, errors and local disk?
  • Have you rehearsed a bucket outage?

22Real-World Usage Patterns

Where does tiering pay off in practice? These patterns show up again and again in production.

Long-term event history for audit and replay

Payment and trading platforms often need to reconstruct what happened months ago. With tiering, the event log itself can keep that history at a manageable cost, instead of being duplicated into a separate archive that must be kept in sync.

Fast scaling for very large platforms

Companies that operate huge Kafka fleets, Uber being a well-known example, care about how long it takes to replace a broker or add capacity. Keeping only a recent window on each broker makes these operations far quicker.

Backfills and machine learning

Data teams frequently need to feed months of past events into a new model or a new service. Reading the history straight from Kafka means one source of truth and no need to run a separate export job first.

Telemetry and log pipelines

Clickstreams, metrics and application logs are big and only occasionally re-read. They are ideal for a short local window and a long remote history.

The vendor landscape

PlatformHow tiering is offered
Apache Kafka (open source)Built-in framework from KIP-405, with pluggable storage backends. Production ready from 3.9
ConfluentTiered storage in its commercial platform and cloud service, with its own tuned implementation
Amazon MSKTiered storage for provisioned clusters, backed by Amazon’s own storage layer
RedpandaBuilt-in cloud storage tiering, designed into the broker from the start
Apache PulsarOffloads older segments of its storage layer to object storage

Questions to ask a managed service provider

Many teams will not run the plugin themselves but will buy tiered storage as part of a managed Kafka service. That is a sensible choice, but the details still matter. Before you sign, ask a few plain questions and expect plain answers.

Retention

What are the limits?

Is there a maximum total retention, a minimum local retention or a cap on storage per topic?

Pricing

What is billed?

Is remote storage billed per gigabyte only, or are requests and data transfer included? Are reads of old data charged separately?

Topics

Which topics qualify?

Are compacted topics excluded? Can tiering be turned on for existing topics?

Exit

Can I leave?

If you move away from the service, can you get your history back out in a usable form?

Security

Who holds the keys?

Where is the bucket, who can access it, and can you bring your own encryption keys?

Support

How are incidents handled?

What alerts and metrics do you get about the remote tier, and who is responsible when it misbehaves?

Deciding whether you need it

Your situationVerdict
Retention of days to years on high-volume topicsStrong fit
Brokers added mostly to get more diskStrong fit
Rebalancing takes many hoursStrong fit
Small cluster, one or two days of dataProbably unnecessary
Mostly compacted topicsNot supported for those topics

23Tiered Storage Compared With Other Approaches

Tiering is one answer to the long-retention problem. Here is how it stacks up against the alternatives teams often consider.

ApproachHow it worksStrengthsWeaknesses
Bigger disks or more brokersKeep everything local and pay for itSimplest; fastest reads for all dataCostly; slow recovery; wasted compute
Export to a data lake with a connectorCopy topic data into files for analytics toolsGreat for queries and reportsSecond copy; different format; replays back into Kafka need extra work
Archive cluster with cheap disksMirror topics into a second Kafka clusterKafka clients work unchangedStill pays for disk and brokers; more clusters to run
Kafka tiered storageOne log split across local disks and object storageOne source of truth; cheap history; faster operationsSlower old reads; more parts to secure and monitor
Other systems with built-in offloadChoose a platform that separates storage by designDeep integrationMigration effort; different ecosystem

Tiering and the data lake are friends

Teams sometimes think they must choose between tiered storage and a data lake. They solve different problems. Tiering keeps history inside Kafka for replay by streaming applications. A data lake stores data in analytics-friendly formats for queries, dashboards and reports. Many mature platforms run both: Kafka with tiering for the event log, and a connector that lands selected topics into the lake.

Analogy

Tiered storage is like a museum that keeps its own basement archive of original artefacts. A data lake is like a photo book made from those artefacts for visitors who want to browse. The photo book is easier to flip through. But if you need the real artefact, you go to the basement.

Looking ahead

The Kafka community is discussing designs that go further than tiering, such as writing data straight to object storage without local replication for some topics. These ideas trade latency for even lower cost and simpler operations. They are proposals and experiments today. Choose the tools that are stable in your Kafka version, and revisit the field as it matures.

24Advantages, Disadvantages and Trade-offs

A fair look at both sides, so you can decide with clear eyes.

Advantages

  • Storage cost drops sharply for long retention
  • Storage grows independently of the number of brokers
  • Broker replacement and scale-out become much faster
  • Consumers and producers need no code changes
  • Months or years of history live in one place
  • Replays are less likely to disturb real-time readers

Disadvantages

  • Reads of old data are slower to start
  • More moving parts: plugins, bucket, catalogue
  • Compacted topics are not supported
  • The bucket becomes a critical dependency and a security target
  • Extra network traffic and request charges
  • Older Kafka versions lack production-ready support

Classic Kafka against tiered Kafka

DimensionClassic KafkaKafka with tiered storage
Where old data livesBroker disks, three copiesObject storage, one logical copy
Cost of long retentionHigh and linearLow and gentle
Broker recovery timeGrows with total dataGrows with the local window only
Latency for old dataDisk speedNetwork and object store speed
Failure surfaceBrokers onlyBrokers, bucket, catalogue
Best useShort retention, ultra-low latencyLong retention, elastic operations
i
The core trade

You give up a little read speed on old data and accept a larger system, and in return you gain cheap history and easy operations. For many teams, that is an excellent bargain. For latency-obsessed, short-retention workloads, it is not.

25Best Practices and Design Patterns

A compact playbook drawn from everything above.

1

Start with the heavy hitters

List your topics by disk usage. Tier the top few first and measure the effect before widening.

2

Size the hot window from real behaviour

Look at how far behind the tail your normal consumers read, add room for outages and restarts, and set local retention from that.

3

Tune segment size

Use moderate sizes for busy topics, and an age limit for quiet ones, so segments reach the remote tier in good time.

4

Put guard rails around the remote path

Apply copy and read throttles and client quotas so that batch jobs never crowd out real-time traffic.

5

Keep the bucket close and private

Same region, private network path, encryption on, public access blocked, least-privilege identity.

6

Alert before it hurts

Watch copy lag, error rates and local disk usage. A rising disk line is the earliest sign that uploads are stuck.

7

Rehearse failures

Simulate a bucket outage, a broker loss and a metadata topic problem in staging, and write down what you saw.

Design patterns that work well

Pattern

Hot window, cold history

Short local retention for speed and a long total retention for memory. The most common setup.

Pattern

Replay in its own lane

Give replay jobs their own client identity and quota, so they are easy to limit and easy to observe.

Pattern

Event log as system of record

Treat Kafka with unlimited retention as the master record, and rebuild downstream stores from it when needed.

Pattern

Gradual rollout

Enable on one topic, then a team, then the cluster, checking cost and latency at each step.

26A Safe Rollout Plan

The safest way to adopt tiering is slowly, with a way back at every step. This plan works for both small and large clusters.

Phase 1: prepare

Upgrade to a Kafka version where tiered storage is production ready, or use a managed service that offers it. Choose and test a plugin in a staging cluster. Create the bucket, the role, the encryption keys and the network path. Write down who owns the bucket, because ownership gaps cause the worst incidents.

Phase 2: pilot on one topic

Choose a large but low-risk topic. Enable tiering, but leave local retention equal to total retention at first. This means nothing is deleted locally yet, so if anything goes wrong, all data is still on the brokers. Wait until the copy lag metric falls to near zero and the remote log size matches your expectation.

Phase 3: verify reads

Before removing any local data, prove that remote reads work. Use a test consumer to read from the beginning of a tiered segment range and compare counts and sample content with the original. Test with restarts and with a simulated leader change.

Phase 4: shrink the local window gradually

Now lower local retention in steps, for example from 30 days to 14, then 7, then 3, then 1. After each change, wait long enough to see disk usage fall, and check latency for your real-time consumers. Stop as soon as a consumer complains or metrics show pressure.

Phase 5: expand and operate

Repeat for other large topics. Add alerts, dashboards and run books. Practise the failure scenarios. Review costs each month against your prediction.

Exit check

Copy lag is stable

Uploads keep pace with closing segments even at peak load.

Exit check

Reads verified

A full-history read returns the exact expected data.

Exit check

Alerts fire in tests

A deliberate permission failure in staging triggers the right page.

Exit check

Rollback rehearsed

The team has practised disabling tiering on a test topic and knows what happens to the remote data.

!
Golden rule

Never reduce local retention until you have watched a full read from remote storage succeed. Trust, then verify, then shrink.

27Plain-English Glossary

A quick reference for every term used in this guide, in the simplest words we can find.

TermMeaning
BrokerA Kafka server that receives, stores and serves messages
TopicA named stream of messages, such as orders or payments
PartitionOne ordered slice of a topic, spread across brokers for parallel work
OffsetThe position number of a message inside a partition
SegmentOne file-sized piece of a partition’s log
Active segmentThe newest segment, still open for new writes
Rolled or closed segmentA segment that no longer accepts writes and never changes again
ReplicaA copy of a partition kept on a broker
Leader and followerThe replica that handles all traffic, and the replicas that copy it
In-sync replica setThe replicas that are fully caught up with the leader
Leader epochA counter that increases each time a new leader is chosen
RetentionThe rule that says how long or how much data to keep
Local tierData stored on the broker’s own disks
Remote tierData stored in an external system such as object storage
Log start offsetThe first offset that still exists anywhere in either tier
Local log start offsetThe first offset that still exists on the broker’s own disks
Last stable offsetThe point below which all transactions are finished
RemoteLogManagerThe broker component that coordinates everything about the remote tier
RemoteStorageManagerThe plugin that stores and retrieves segment files
RemoteLogMetadataManagerThe plugin that keeps the catalogue of remote segments
Object storageA service that stores large files as named objects, such as Amazon S3
Page cacheMemory the operating system uses to hold recently used file data
Throttle or quotaA limit on how fast data may be copied or read
ReplayReading old messages again from an earlier offset

28Frequently Asked Questions

Q1Do I need to change my producers or consumers?
No. Clients use the same protocol and the same offsets. The broker decides where to read from. The only visible change is that fetches for old data have a higher start-up time.
Q2Does tiered storage make Kafka faster?
No. It makes storage cheaper and operations lighter. Reading recent data is as fast as before. Reading old data is somewhat slower than reading it from a local disk.
Q3Is the active segment ever sent to remote storage?
No. Only closed segments are copied, and only after all of their messages are stable. The active segment always stays on the broker.
Q4What happens to my data if the bucket is down?
Producing and reading recent data continue normally. Reads of old data fail, and uploads pause. Because local segments cannot be deleted until copied, local disks begin to fill, so long outages need attention.
Q5Which storage systems can I use?
Any system for which a storage plugin exists. Plugins are available for the major cloud object stores and for file systems such as HDFS. The plugin must match your Kafka version.
Q6Can I use it with compacted topics?
No. Compacted topics are not supported, because compaction rewrites old segments and the remote copies are meant to be immutable.
Q7Can I turn it off later?
From Kafka 3.9 onwards, tiering can be disabled on a topic, with a choice about what happens to the remote data. Earlier versions did not support a safe exit, so test carefully.
Q8Does it reduce the replication factor?
No. Local data is still replicated across brokers. What changes is that only the local window is replicated. Older data is stored once in the remote system, which provides its own durability.
Q9Is my data safe in the bucket?
Object stores are built for very high durability, but safety also depends on your configuration. Restrict deletion rights, use encryption, and keep Kafka in charge of deleting objects.
Q10How is this different from copying topics to a data lake with a connector?
A connector makes a separate copy in another format for other tools to query. Tiered storage keeps the data in Kafka’s own format and lets Kafka clients read it directly. They solve different problems, and some teams use both.
Q11Why did my local disks not shrink after enabling it?
Common causes are that local retention was left at its default, segments have not closed yet, or uploads are failing. Check the local retention values, segment settings and copy error metrics.
Q12How long does the first copy take on an existing topic?
It depends on how much closed data exists and how fast the throttles allow uploads. Expect a steady background process rather than an instant switch, and watch the copy lag metric until it falls.

29Summary and Key Takeaways

Key Takeaways

  • One log, two homes. Recent segments stay on fast broker disks, older segments live in cheap object storage, and clients see a single continuous log.
  • Four parts do the work. The local log, the RemoteLogManager, the storage plugin and the metadata plugin work together, with the leader doing all the uploading.
  • Only closed, stable segments move. Local copies are deleted only after the upload is confirmed, which protects against data loss.
  • Two clocks control retention. Total retention decides how long data exists at all, and local retention decides how long it stays on brokers.
  • Operations get lighter. Because followers copy only the local window, broker replacement and scaling can shrink from a day to about an hour.
  • The savings can be large, but so is the responsibility. Long retention gets far cheaper, while the bucket, the catalogue and the plugin become part of your critical path.
  • Know the limits. Compacted topics are not supported, old data reads are slower to start, and settings such as segment size and local retention need real testing.