The KRaft Metadata Log in Apache Kafka
A deep, plain-English tour of the single replicated log that now holds every fact about a Kafka cluster: how it is written, agreed upon, compacted into snapshots, replayed by brokers, and kept healthy in production.
Imagine a large school with hundreds of classrooms, teachers and students. Somewhere there is a big register that says which teacher owns which class, which room is locked, and who moved where this morning. If two office clerks keep two different registers, chaos follows: one teacher walks into a room that the other register says belongs to someone else. Apache Kafka faces this exact problem every second, because a cluster is really a crowd of servers that must all agree on one version of the truth.
For many years Kafka kept that register in a separate system called ZooKeeper. Today the register lives inside Kafka itself, in a special log called the metadata log. This tutorial explains that log from the ground up. We start with the simplest ideas and slowly climb to the advanced mechanics that architects and site-reliability engineers need when they run large clusters.
1Why Kafka Needs a Metadata Log
Before we open the log, we must understand the problem it solves and the older solution it replaced.
What is metadata?
Metadata simply means data about data. When you send a message to Kafka, the message itself is the data. Facts such as “this topic exists”, “it has twelve partitions”, “partition seven lives on brokers one, four and nine” and “broker four is the leader for partition seven” are metadata. Without metadata, brokers would not know where anything lives, and clients would not know whom to talk to.
Metadata changes far less often than messages, but it is far more important. A wrong message affects one consumer. A wrong piece of metadata can make two brokers both believe they are the leader of a partition, and that can corrupt data for everyone.
Think of a library. The books are the messages. The card catalogue that says which shelf holds which book is the metadata. If the catalogue is wrong, the books are still there, but nobody can find them, and two librarians might shelve different books in the same spot.
How the old design worked
In the original design, one broker was elected as the controller. The controller made decisions such as choosing new partition leaders when a broker died. But the permanent record of the cluster lived in ZooKeeper, a separate cluster of servers. Every broker also kept its own cached copy, and the controller pushed updates to brokers using direct remote calls.
This meant two systems to install, secure, monitor, upgrade and understand. It also meant that the truth was stored in one place (ZooKeeper) while decisions were made in another (the controller), and the two could briefly disagree.
The pain points that motivated a change
Two systems to run
Teams had to operate Kafka and ZooKeeper, each with its own configuration, security model and failure modes.
Slow controller failover
A new controller had to read the entire cluster state from ZooKeeper before it could work, which took longer as the cluster grew.
Partition scaling limits
Pushing updates to every broker one call at a time became a bottleneck when a cluster held very large numbers of partitions.
Inconsistent views
Because brokers received updates by push, a broker could miss one and drift out of sync until a full refresh happened.
The big idea: metadata as an event log
The Kafka community proposed a change in an improvement proposal known as KIP-500. Instead of storing the cluster state in an outside database, Kafka would record every change to that state as an event in a log, and a small group of servers would agree on that log using a consensus algorithm called Raft. Brokers would no longer be told about changes by push. They would simply read the log, the same way a consumer reads a topic.
That log is the KRaft metadata log. The name KRaft is short for Kafka Raft. It is the heart of how a modern Kafka cluster knows what it is.
KRaft became usable for new clusters in the 3.x line, migration from ZooKeeper matured in later 3.x releases, and Kafka 4.0 removed ZooKeeper entirely. On any current Kafka release, KRaft is the only way to run a cluster.
2What Exactly Lives in Cluster Metadata
The metadata log stores much more than a list of topics. It is the complete description of the cluster.
Every durable fact that must survive a restart and be agreed upon by every server belongs in the metadata log. If you could freeze a cluster and write down everything a brand-new broker would need to behave correctly, that list is the metadata.
Topics and partitions
Names, unique identifiers, partition counts, replica lists, in-sync replica sets and current leaders.
Broker registrations
Which brokers exist, their addresses, racks, and whether each one is active, fenced or shutting down.
Dynamic configuration
Topic-level and broker-level settings that were changed while the cluster was running.
Security records
Access control entries, SCRAM credentials and delegation tokens used to authenticate and authorize clients.
Client quotas
Rate limits assigned to users, client identifiers or combinations of both.
Feature levels
The cluster-wide metadata version and other feature flags that decide which behaviours are allowed.
Producer ID blocks
Ranges of producer identifiers handed out so that idempotent and transactional producers never collide.
What is deliberately not in the metadata log
Your actual messages are never stored in the metadata log. Consumer group offsets are kept in an internal topic managed by the group coordinator, not here. Transaction state has its own internal topic too. The metadata log is intentionally small and focused: it holds the cluster’s structure and rules, not its traffic.
Many beginners assume the metadata log is where consumer offsets live. It is not. Losing the metadata log would make the cluster forget its topics, but it would not, by itself, be the place where offsets are tracked.
3Raft Consensus in Plain English
To trust the metadata log, you must first understand how a group of servers agrees on anything at all.
The agreement problem
Suppose three servers each hold a copy of the register, and a request arrives: “create topic orders”. If server A records it but B and C never hear about it, the copies disagree. If A then crashes, the change may be lost even though a client was told it succeeded. Consensus algorithms exist to prevent exactly this. They give a strict rule: a change only counts once a majority of servers have safely stored it.
Picture five friends deciding where to eat by text message. One friend acts as the organizer. A plan is only final once at least three friends reply “yes”. Even if two friends lose their phones, the group still has a valid decision that at least one surviving friend remembers.
The core vocabulary
Voter
A server allowed to vote in elections and whose storage counts toward a majority.
Leader
The one voter that accepts new records at any moment. In Kafka this is the active controller.
Follower
A voter that copies the leader’s log and can stand for election if the leader disappears.
Observer
A server that reads the log but does not vote. In Kafka, ordinary brokers are observers.
Epoch
A counter that increases each time a new leader is elected. It works like a reign number that outdated leaders cannot forge.
Committed
A record that a majority has stored. Committed records are never lost or reordered.
Majorities and fault tolerance
The magic of a majority is that any two majorities must overlap by at least one server. That overlapping server remembers the latest decision, which is why the group never forgets committed history. The price is that you can only tolerate a minority of failures.
| Voters | Majority needed | Failures tolerated | Comment |
|---|---|---|---|
| 1 | 1 | 0 | Fine for local learning, unsafe for real use |
| 2 | 2 | 0 | Worse than one in practice; two things can fail instead of one |
| 3 | 2 | 1 | The common production choice |
| 4 | 3 | 1 | No better than three, with more cost |
| 5 | 3 | 2 | For very large or very critical clusters |
Why Kafka adapted Raft
Standard Raft has the leader push new entries to followers. Kafka’s version is pull-based: followers issue fetch requests to the leader, exactly like consumers and follower replicas already do elsewhere in Kafka. This let the Kafka team reuse existing code, existing network protocols and existing operational knowledge. It also made it natural for non-voting brokers to follow the same log with the same mechanism.
Because both voters and observers just fetch, the leader does not need to keep track of who is a “subscriber”. Anyone who can talk to the leader can follow the log.
4Anatomy of the Metadata Log
The metadata log looks a lot like a normal Kafka topic, with a few important twists.
A special one-partition topic
The log is stored as an internal topic named __cluster_metadata with exactly one partition. There is no need for more, because metadata changes must be strictly ordered. A single ordered stream is the simplest way to guarantee that every server replays the same changes in the same order and therefore reaches the same state.
A bank ledger is one long book, not ten books read in parallel. If you want everyone to compute the same balance, everyone must read the same entries in the same order. The metadata log is that single ledger for the cluster.
Offsets, epochs and record batches
Every record has an offset, which is its position in the log, starting from zero and rising by one. Every batch of records is also stamped with the leader epoch under which it was written. Together, the pair of offset and epoch uniquely identifies a point in history. This pair is how servers detect and repair disagreements after a leader change.
Records are grouped into batches for efficiency, exactly as in ordinary topics. The active controller may combine several small changes into one batch, and a single client request can produce more than one record. Creating a topic with three partitions, for example, yields a record for the topic and separate records for each partition.
Where the log lives on disk
Each controller and each broker keeps its own copy of the log in a directory chosen by the metadata log directory setting. If that setting is empty, Kafka uses the first data directory. The directory contains segment files, index files and, as we will see later, snapshot files. Because losing this directory means losing a server’s local memory of the cluster, many operators place it on a dedicated, reliable disk.
| Property | Ordinary topic | Metadata log |
|---|---|---|
| Partitions | Many | Exactly one |
| Who writes | Producers | Only the active controller |
| Who reads | Consumers | Brokers and other controllers |
| Replication | ISR-based | Raft majority-based |
| Cleanup | Retention or compaction | Snapshots then truncation |
| Leader chosen by | Controller | Raft election among voters |
Although it is stored using familiar log machinery, you must never produce to it, delete it or alter its files by hand. It is governed by the Raft protocol, not by the topic tools you use for application data.
Durability first
Raft’s safety depends on a server never telling the leader “I have stored this record” unless the record would survive a crash. For that reason the metadata log is written with a strong durability posture, flushing data to disk aggressively rather than trusting the operating system to do it later. This makes metadata writes a little slower than ordinary message writes, but metadata changes are rare and precious, so the trade is worth it.
5Architecture: Controllers, Brokers and the Quorum
A KRaft cluster is made of servers that play different roles around one shared log.
Process roles
Each Kafka process declares what it does through a role setting. A process can be a broker, a controller, or both at once. Brokers serve clients and store message data. Controllers hold the metadata log as voters and, one at a time, act as the leader that makes cluster decisions.
Dedicated controller
Runs only the metadata quorum. Recommended for production because metadata work is never starved by message traffic.
Dedicated broker
Serves produce and fetch requests and follows the metadata log as an observer.
Combined node
Does both jobs in one process. Convenient for development laptops and tiny test clusters.
Active controller
The single voter currently holding leadership. It is the only server that appends metadata records.
flowchart TB
subgraph Q["Controller quorum - voters"]
C1["Controller 1 - active leader"]
C2["Controller 2 - follower"]
C3["Controller 3 - follower"]
end
C2 -->|"fetch metadata log"| C1
C3 -->|"fetch metadata log"| C1
B1["Broker 1 - observer"] -->|"fetch metadata log"| C1
B2["Broker 2 - observer"] -->|"fetch metadata log"| C1
B3["Broker 3 - observer"] -->|"fetch metadata log"| C1
B1 -->|"heartbeat"| C1
B2 -->|"heartbeat"| C1
B3 -->|"heartbeat"| C1
CL["Admin client"] -->|"create topic"| C1
How the quorum is described
In the classic setup, an operator lists every voter, with its numeric identifier and address, in the quorum voters setting. Every controller and every broker receives the same list, so everyone knows whom to ask. In newer releases with dynamic quorums, a bootstrap list is used only to find the quorum, and the true voter set is stored inside the log itself. We cover that in detail later.
Two separate networks of conversation
It helps to keep two conversations apart in your mind. The first is the client conversation: producers and consumers talk to brokers about messages. The second is the control conversation: brokers and controllers talk about cluster state. Controllers listen on their own dedicated listener, named by the controller listener names setting, so control traffic can be secured and firewalled separately.
A restaurant has a dining room where guests are served and a manager’s office where staffing and the reservation book are handled. Guests never need to enter the office, and the office has a separate door. Controllers are the manager’s office; brokers are the dining room.
Controllers need modest CPU and memory but reliable disks and low-latency networking between them. Three dedicated controllers cover most clusters. Choose five only when you truly need to survive two simultaneous controller failures.
6The Vocabulary of Metadata Records
Every change to the cluster becomes a small, typed record. Learning the main types is like learning the verbs of the cluster’s language.
The metadata log does not store a giant picture of the cluster. It stores a story of changes. Each record says “this happened” or “this is now true”. A server that reads the story from the beginning ends up with the same picture as every other server that read the same story.
Topic record
Announces a new topic with its name and a unique identifier that never changes, even if the topic is later renamed in tooling.
Partition record
Describes one partition: its replicas, its in-sync replicas, its leader and the leader epoch.
Partition change record
A compact update to an existing partition, such as a new leader or a shrunken in-sync set, instead of repeating everything.
Register broker record
Says a broker has joined, with its incarnation identifier, endpoints, rack and supported feature range.
Fence and unfence records
Mark a broker as temporarily not eligible to lead partitions, or as eligible again once it has caught up.
Config record
Stores one dynamic setting for a topic, a broker or the whole cluster.
Feature level record
Sets the level of a named feature, including the cluster-wide metadata version.
Remove topic record
Says a topic no longer exists. Deletion is also an event, not an erasure of history.
More record families you will meet
There are also records for client quotas, access control entries and their removal, SCRAM credentials, delegation tokens, producer identifier blocks, and internal housekeeping such as no-op records. A no-op record is a harmless heartbeat the leader can append so the committed point of the log keeps advancing even when nothing else is happening.
Newer releases also have transaction marker records. When a single administrative request needs to change several things atomically, such as creating a topic together with all its partitions, the controller can wrap its records between a begin marker and an end marker. Readers apply the whole group or none of it. If the leader fails halfway, an abort marker lets everyone discard the partial group.
A checkout basket. Nothing in the basket belongs to you until you pay at the till. The begin and end markers are the moment you pick up the basket and the moment you pay: either everything in it is yours, or none of it is.
| Event in the real world | Records typically appended |
|---|---|
| A new broker starts for the first time | A registration record, later an unfence record |
| An admin creates a topic with three partitions | One topic record and three partition records |
| A broker crashes | A fence record, then partition change records for every partition it led |
| An operator raises a topic retention setting | One config record |
| An administrator grants a user read access | One access control entry record |
| The cluster is upgraded and the version is raised | One feature level record |
Because partition changes are recorded as tiny deltas, a leader election affecting a thousand partitions produces a thousand small records rather than a thousand full descriptions. That keeps the log compact and keeps replication fast.
7Life of a Metadata Change: Creating a Topic
Following one request from start to finish shows how all the pieces cooperate.
Let us trace what happens when an administrator asks the cluster to create a topic named orders with three partitions. Along the way you will see the active controller, the followers, the commit rule and the brokers each play their part.
Request arrives at the active controller
The admin client discovers the active controller through a broker and sends a create-topic request. A follower controller would reject or redirect it, because only the leader may change metadata.
Validation and planning
The controller checks that the name is legal, that it does not already exist, and that enough healthy brokers exist to place the requested replicas. It then chooses which brokers will host each partition, spreading replicas across racks when rack information is available.
Records are produced
The controller creates the topic record and the partition records and applies them to its own in-memory state, tentatively. It also hands them to the Raft layer to be appended to the log.
Followers fetch and store
Each follower controller asks the leader for new records, writes them to its own disk, and reports how far it has got in its next fetch request.
Majority reached, record committed
Once a majority of voters, counting the leader, have stored the records, the leader advances the committed point, called the high watermark.
The client gets its answer
Only now does the controller reply to the admin client with success. The answer is never sent before the change is safe.
Brokers learn and act
Brokers, which are also fetching the log, read the new records, update their in-memory picture, and the brokers chosen as replicas create the partition directories and start replicating. The chosen leaders begin serving traffic.
sequenceDiagram
participant A as Admin client
participant L as Active controller
participant F as Follower controllers
participant B as Brokers
A->>L: Create topic orders
L->>L: Validate and plan replicas
L->>L: Apply tentatively in memory
F->>L: Fetch new records
L-->>F: Topic and partition records
F->>L: Fetch again, reporting stored offset
L->>L: Majority stored, advance high watermark
L-->>A: Topic created
B->>L: Fetch committed records
L-->>B: Topic and partition records
B->>B: Create local partitions
A town clerk drafts a new law, three council members each copy it into their own books, and only when two of the three confirm do they announce it to the public. Neighbors then read the announcement board and adjust their behavior. Nobody acts on a law that could still be lost.
Brokers and followers only ever see committed records. That guarantees no broker will act on a change that later disappears because of a leader failure.
8Inside the Active Controller
The active controller is a carefully engineered single-threaded engine. Understanding it explains both its speed and its limits.
One thread, one queue, no locks
The controller component in KRaft processes every request as an event on a single queue, handled by a single thread. This may sound slow, but it removes an entire class of bugs. With only one thread changing the state, there are no race conditions, no locks to reason about, and every request sees a consistent world. Because each event is small and the state lives in memory, this design is very fast in practice.
A single skilled bank teller calling one customer at a time can process transactions very quickly and never mixes up two people’s accounts. Adding a second teller who shares the same ledger would need constant coordination. One fast teller is simpler and safer.
Speculative execution with rollback
Here is the clever part. When the controller handles a request, it does not wait for the majority before updating its in-memory state. It applies the change immediately, so the next request can build on it. But those changes are provisional until committed. The controller keeps its state in special data structures that remember earlier versions, called timeline structures. If the leader loses its position before the change is committed, it simply rewinds its memory to the last committed point and forgets the uncommitted changes.
This lets the controller pipeline many requests without waiting for each one to be replicated. Throughput rises, while safety stays intact because no reply is sent to a client until its records are committed.
flowchart LR
R["Client request"] --> Q["Single event queue"]
Q --> V["Validate against in-memory state"]
V --> G["Generate records"]
G --> M["Apply provisionally to timeline state"]
G --> P["Append to Raft log"]
P --> H{"Majority stored?"}
H -->|"yes"| C["Mark committed and reply to client"]
H -->|"leadership lost"| X["Roll back to last committed state"]
Batching and linger
Appending each tiny record separately would waste disk and network effort. The controller therefore groups records that arrive close together and waits a short moment, a linger time, before handing a batch to the Raft layer. Larger batches raise throughput, and the short wait keeps latency low. Operators rarely need to tune this, but it explains why bursts of topic creation are handled gracefully.
Background duties of the controller
Leader election for partitions
When a broker fails or is shut down, the controller picks new partition leaders from the in-sync replicas.
Processing ISR changes
Partition leaders ask the controller for permission to shrink or grow the in-sync set, so the change is recorded and agreed.
Membership tracking
Registers brokers, tracks their heartbeats and fences the ones that go silent.
Producer ID allocation
Hands out blocks of identifiers so producers can be idempotent without central chatter per message.
Configuration and ACL changes
Turns administrative changes into records so every broker applies them consistently.
Preferred leader rebalancing
Periodically nudges leadership back to preferred replicas to keep the load balanced.
Because a single thread does all this work, an expensive request can delay others. This is why controllers should be given fast CPUs and why you should avoid flooding them with huge administrative operations during busy periods.
9Leader Election and Epochs
The quorum must always have exactly one legitimate leader. Epochs are the tool that guarantees this even during chaos.
States of a voter
At any moment a voter is in one of a few states. A follower is following a known leader. A candidate is asking others to vote for it. A leader is the winner and is serving requests. There is also an unattached state where a voter does not currently know who leads, and a resigned state for a leader that is stepping down gracefully.
How an election unfolds
Silence from the leader
A follower notices that its fetch requests to the leader are failing or timing out for longer than the fetch timeout.
Waiting a random moment
The follower waits for a randomized election timeout. The randomness prevents all followers from becoming candidates at exactly the same instant.
Becoming a candidate
The follower increases the epoch by one, votes for itself, and sends vote requests to the other voters, describing how up to date its log is.
Voters decide
Each voter grants its vote only if the candidate’s log is at least as complete as its own and it has not already voted in that epoch. This rule means a server missing committed records can never win.
Majority wins
When a candidate collects a majority of votes, it becomes the leader of the new epoch and tells the others by a begin-epoch message. It typically appends a small record to establish its leadership.
Followers realign
Followers begin fetching from the new leader. If their logs contain uncommitted tails from the old leader, those tails are truncated to match the new leader’s history.
Think of a classroom whose monitor stops responding. After a random pause, one student declares “I will be the monitor for term two” and asks classmates to agree. Only students who have all the recent notes can be elected, so the new monitor is never missing important announcements. Each term has a number, and orders from an old term are ignored.
Epochs as fencing tokens
Every message between voters carries the sender’s epoch. If a server receives a message with a lower epoch than it knows, it rejects it and tells the sender the newer epoch. A former leader that was merely slow, or cut off by a network problem, discovers on its first contact that time has moved on and immediately steps down. This is what prevents two servers from both acting as leader in the same epoch.
stateDiagram-v2
[*] --> Follower
Follower --> Candidate: leader silent, election timeout fires
Candidate --> Leader: majority of votes received
Candidate --> Follower: another leader found or higher epoch seen
Candidate --> Candidate: split vote, new epoch
Leader --> Follower: higher epoch seen
Leader --> Resigned: graceful shutdown
Resigned --> Follower
Pre-vote to prevent disruption
A known weakness of basic Raft is that a server cut off from the network keeps raising its epoch. When it rejoins, its high epoch forces the healthy leader to step down for no good reason. Newer Kafka releases address this with a pre-vote step: before raising the epoch, a would-be candidate asks whether others would grant a vote. If the leader is still healthy for them, the answer is no, and no disruption happens.
There are two different kinds of leader election in Kafka. Raft elects the active controller among voters. The active controller then elects partition leaders among in-sync replicas. They are separate mechanisms at separate levels.
10Replication, the High Watermark and Log Repair
Replication is where the safety promises of Raft become concrete.
Pull-based replication in detail
Followers and observers send fetch requests to the leader. Each request says, in effect, “I have everything up to this offset, and the last record I have was written in this epoch. What comes next?” The leader replies with the next batch. Because the request contains both the offset and the epoch of the last record, the leader can instantly check whether the requester’s history matches its own.
Detecting divergence
If the requester claims a position that the leader’s log does not contain, or that was written in a different epoch, the leader responds with a hint: the last offset and epoch where the histories agree. The requester then truncates its log back to that point and resumes fetching. This is how a former leader with uncommitted records, or a follower that was offline, is brought back into line with the true history.
Two students copy a teacher’s notes but one wrote a wrong line before the teacher corrected it. When they compare, they find the last line where both notebooks match, erase everything after it in the wrong notebook, and copy the teacher’s version from there.
The high watermark
The leader tracks how far each voter has replicated. The high watermark is the highest offset that a majority of voters have stored. Everything at or below it is committed. The leader advertises the high watermark in every fetch response, so followers and brokers know which records are safe to apply.
| Situation | What Raft does |
|---|---|
| Follower is a few records behind | It simply fetches the missing records |
| Follower has extra uncommitted records from an old epoch | Leader points to the divergence point; follower truncates then fetches |
| Follower is so far behind that old records were already cleaned up | It downloads a snapshot first, then fetches the remainder |
| A minority of voters is unreachable | The quorum keeps committing with the majority |
| A majority of voters is unreachable | No new commits are possible until enough voters return |
Adding brokers does not slow down commits, because observers never count toward the majority. You can grow the number of brokers to hundreds while the number of voters stays at three or five.
11Snapshots: Keeping the Log From Growing Forever
A log that only ever grows would eventually be too large to replay. Snapshots are the solution.
The problem of an endless story
Imagine a cluster that has existed for years. Millions of records describe every topic ever created, every broker that ever joined and every setting that was ever changed. A brand-new broker replaying all of that from the beginning would take a very long time, and disks would fill with ancient history. Most of those old records have long been superseded by newer ones.
A company keeps every invoice ever issued, but each year the accountants also produce a year-end balance sheet. A new accountant does not read fifty years of invoices. They start from the latest balance sheet and read only the invoices after it.
What a snapshot is
A snapshot is a file containing the complete state of the cluster at one exact point in the log, written as a compact series of the same kinds of records. It is labeled with the end offset and the epoch that it represents, so its meaning is unambiguous. It begins with a header record and finishes with a footer record so that readers can tell a complete snapshot from a partial one.
Unlike ordinary Kafka topics, which may use log compaction, the metadata log uses snapshots followed by truncation. Once a snapshot exists that covers everything up to some offset, the older log segments up to that point can be safely deleted.
Who creates snapshots
Every controller and every broker builds its own snapshots from its own in-memory state, independently. Because all servers apply the same committed records in the same order, their snapshots at the same offset describe exactly the same state. There is no need to ship snapshots around for routine cleanup.
Bytes since last snapshot
When enough new record data has accumulated since the previous snapshot, a new one is cut. The default threshold is on the order of tens of megabytes.
Time since last snapshot
Even during quiet periods, a snapshot is taken after a maximum interval, on the order of an hour by default.
Startup and load
A server that loads a snapshot at boot may be in a position to record its own fresh one after catching up.
Log truncation
Segments fully covered by a snapshot and past the retention limits become eligible for deletion.
Snapshots for lagging servers
Suppose a broker was offline for a day and, while it was gone, the leader deleted old segments. When the broker returns and asks for a record that no longer exists, the leader replies that the position is too old and points to its latest snapshot. The broker then downloads that snapshot in chunks using a dedicated snapshot-fetch request, loads it, and continues from the snapshot’s end offset by fetching ordinary records.
sequenceDiagram
participant B as Lagging broker
participant L as Leader controller
B->>L: Fetch from offset 100
L-->>B: Offset too old, snapshot available at 5000
B->>L: Fetch snapshot chunk 1
L-->>B: Chunk 1
B->>L: Fetch snapshot chunk 2
L-->>B: Chunk 2
B->>B: Load snapshot and rebuild state
B->>L: Fetch from offset 5000
L-->>B: Regular records
Fast restarts
When a controller or broker restarts, it loads its latest local snapshot and then replays only the records that came after it. Restart time depends on the snapshot size and the recent tail, not on the entire history of the cluster.
Onboarding new brokers
A brand-new broker downloads the latest snapshot from a controller instead of replaying years of records, which keeps scale-out operations quick.
Forensics and debugging
Snapshots are ordinary files that offline tools can inspect. Engineers can open a copy and browse topics, brokers and configurations without touching a running cluster.
Taking snapshots more often makes restarts and catch-up faster and disk usage smaller, but costs some extra work on the controller. In most clusters the defaults are sensible. Revisit them if you see very long startup times or the metadata directory growing unexpectedly.
12How Brokers Consume the Log: Images, Deltas and Publishers
A raw log is not useful until it is turned into a picture the broker can use quickly.
The metadata image
Each broker maintains an immutable in-memory picture of the cluster called the metadata image. It answers questions such as “who leads partition seven of orders?” in a fraction of a microsecond because it is just data in memory. Immutable means the picture, once built, is never modified. Any thread can read it safely without locks.
Think of a printed map. You never scribble on a map that many people are using. When roads change, the mapmaker prints a new edition and hands it out, while people mid-journey can safely finish using their current copy.
Deltas
When new committed records arrive, the broker does not rebuild the entire image from scratch. It collects the new records into a delta, which describes only what changed. Applying the delta to the previous image produces a new image that shares most of its structure with the old one. This makes updates cheap even in very large clusters.
The loader and the publishers
A component called the metadata loader watches the log. It reads committed batches, builds deltas, produces new images and hands both the delta and the new image to a set of listeners called publishers. Each publisher cares about a specific part of the change and reacts to it.
Replica manager
Starts or stops local partition replicas and switches leadership roles when partition records change.
Group and transaction coordinators
Learn about changes to the internal topics they rely on and take or release responsibility for partitions.
Dynamic config handler
Applies changed settings, such as new throttles or retention values, to the running broker.
Quota and ACL managers
Update rate limits and access rules so that the very next request uses the new policy.
Metadata cache
Serves answers to client metadata requests, telling producers and consumers where partitions live.
Feature and version tracker
Notes the current metadata version so the broker knows which behaviors are allowed.
flowchart LR
LOG["Metadata log - committed records"] --> LD["Metadata loader"]
SN["Latest snapshot"] --> LD
LD --> D["Delta - what changed"]
D --> IMG["New immutable image"]
IMG --> P1["Replica manager"]
IMG --> P2["Coordinators"]
IMG --> P3["Config and quota handlers"]
IMG --> P4["Client metadata cache"]
What happens when a change fails to apply
If the loader cannot apply a batch, for example because of a bug or corrupted data, the broker records a load error and raises alarms through its metrics. Failing loudly is intentional. A broker running with a stale or wrong picture of the cluster could make harmful decisions, so operators are expected to notice and act.
Because brokers pull the log asynchronously, there is always a tiny gap between a change being committed and every broker acting on it. Well-run clusters watch this lag, because a broker that is far behind may serve stale answers to clients.
13Broker Registration, Heartbeats and Fencing
The metadata log is also how the cluster decides which brokers are trustworthy at any given moment.
Joining the cluster
When a broker starts, it first contacts the active controller to register itself. It presents its identifier, a unique incarnation identifier for this particular run, its listeners, its rack and the range of features it supports. The controller checks these, appends a registration record and starts tracking the broker. Newly registered brokers begin in a fenced state.
Fenced and unfenced
A fenced broker is one that is not allowed to lead partitions and is not treated as a healthy destination for new leaders. A broker becomes unfenced only after it has caught up with the metadata log to a recent enough point. This rule stops a broker that has not yet loaded the latest cluster picture from being handed responsibility it cannot handle correctly.
A new lifeguard arrives at the pool. Before being placed on the tall chair, they must read today’s safety notes and the incident log. Until they have, the head guard treats them as a trainee and assigns them no critical duties.
Heartbeats
After registering, each broker sends periodic heartbeats to the active controller. A heartbeat tells the controller three things: I am alive, this is how far I have read in the metadata log, and this is whether I want to be fenced or shut down. If heartbeats stop for longer than the session timeout, the controller fences the broker and moves leadership of its partitions to other replicas.
Register
The broker announces itself and is recorded, initially fenced.
Catch up
The broker reads the metadata log or a snapshot until it is close to the latest committed offset.
Unfence
The controller notices from a heartbeat that the broker has caught up and records that it is now active.
Serve
The broker can now be chosen as a leader and takes client traffic.
Controlled shutdown
When asked to stop, the broker signals its intent via heartbeat. The controller moves its leaderships away first, then permits it to exit, so clients see almost no disruption.
If a broker crashes and restarts quickly, the controller must know that this is a fresh process, not a delayed message from the old one. The incarnation identifier makes each life of a broker distinguishable.
| Broker state | Meaning | Can lead partitions? |
|---|---|---|
| Fenced | Registered but not caught up, or missed heartbeats | No |
| Active | Healthy and caught up | Yes |
| Controlled shutdown in progress | Leaving gracefully | No, leaderships are being moved |
| Unregistered | Removed from the cluster | No |
14Versioning and Safe Upgrades
The metadata log evolves over time. A version system lets a cluster of mixed software agree on what is allowed.
The metadata version
The cluster stores a single number called the metadata version, kept as a feature level record in the log. It controls which record formats and behaviors are permitted. Newer software can understand newer record types, but the controller will not write them until the cluster-wide version allows it.
A group of friends agrees to speak a shared language. When some friends learn a newer, richer dialect, the group waits until everyone has learned it before switching. Until then, the older common language is used so nobody is left confused.
The safe upgrade dance
Upgrade controllers first
Roll new software through the controller quorum one node at a time, leaving a majority healthy throughout.
Upgrade brokers
Roll new software through the brokers, also one at a time, so partitions stay available.
Verify health
Confirm that all nodes are running the new software, that there are no metadata load errors and that lag is normal.
Raise the metadata version
Only after everything is stable, use the features tool to raise the metadata version, unlocking new behaviors.
Raising the metadata version can write records that older software cannot read. Treat that step as a deliberate, hard-to-reverse decision, and keep it separate from the software rollout so you have a stable rollback window.
Feature flags beyond the metadata version
The same mechanism carries other feature levels, such as the level that controls the format of the quorum itself. Brokers and controllers advertise the range of versions they support when they register, and the controller refuses to raise a feature beyond what every member can handle. This protects the cluster from silently splitting into incompatible halves.
15Static and Dynamic Quorums
Who exactly the voters are is itself a piece of agreed information, and Kafka has two ways of handling it.
The static quorum
In the original KRaft design, the list of voters is written into every server’s configuration file. It is simple, but changing it is painful. Adding or replacing a controller means editing files and restarting every node in a careful order. If different nodes hold different lists, the quorum can disagree about what a majority even is, which is dangerous.
The dynamic quorum
Newer Kafka releases introduced dynamic quorum membership. Instead of a fixed list in configuration, the current voter set is stored inside the metadata log itself as a special record, and it changes through the same Raft process as everything else. Servers use a bootstrap list only to find the quorum when they start. Operators can then add or remove controllers with administrative commands while the cluster keeps running.
A club can keep its member list on a laminated card handed to everyone, so every change requires reprinting the card. Or it can keep the member list in its minute book, so a new member is added by a vote recorded in the book. The second way keeps everyone automatically consistent.
Voter identifier plus directory identifier
A voter is identified by its node number and by a unique identifier of its metadata directory, so a wiped disk cannot silently impersonate the old voter.
One change at a time
The quorum changes by a single voter per step, so the old and new majorities always overlap and safety is preserved.
Add a controller
The new node first joins as an observer and catches up fully. Only then is it promoted to a voter.
Remove a controller
A decommissioned voter is removed by a recorded change, and the majority requirement shrinks accordingly.
flowchart LR
S1["New controller starts as observer"] --> S2["Catches up using snapshot and log"]
S2 --> S3["Admin requests add voter"]
S3 --> S4["Leader records new voter set in the log"]
S4 --> S5["Majority commits the change"]
S5 --> S6["Node is now a voter"]
Replacing failed hardware
When a controller machine dies permanently, operators add a fresh node, wait for it to catch up, then remove the dead voter. The quorum never drops below a safe size.
Moving controllers between data centres or zones
New controllers can be introduced in the target location and old ones retired, one step at a time, without a maintenance window.
Growing from three to five voters
As a business becomes more critical, the quorum can be widened without rebuilding the cluster.
Dynamic membership is available in recent Kafka releases and is controlled by a feature level. Confirm your version and the feature level before planning any membership change.
16Failure Scenarios and Recovery
A design is only as good as its behavior on the worst day. Here is what the metadata log does when things break.
Scenario: the active controller crashes
Followers stop receiving responses, wait out a randomized timeout, and elect a new leader whose log is fully up to date. Because every voter already holds the full committed log in local storage and memory, the new leader can begin working within moments, without reloading state from an outside system. Brokers simply redirect their fetches to the new leader.
Scenario: one follower controller fails
Nothing visible happens to clients. The quorum still has a majority. When the follower returns, it fetches what it missed, or downloads a snapshot if it was away for a long time.
Scenario: the majority of controllers fail
No new metadata commits are possible. Existing brokers continue to serve reads and writes to partitions whose leaders are unchanged, but no topic can be created, no leader can be re-elected, and a failing broker will not have its partitions moved. Restoring a majority of voters restores full function without data loss.
Scenario: network partition splits the quorum
The side with a majority elects or keeps a leader and continues. The minority side cannot commit anything and its leader, if it had one, steps down. When the network heals, the minority side truncates any stray uncommitted records and catches up.
Scenario: a broker is cut off from controllers
It stops heartbeating and is eventually fenced. Its partitions get new leaders elsewhere. When connectivity returns, it must catch up on metadata before being unfenced.
Scenario: a controller disk fills or is lost
A controller that cannot write is unable to participate. If its disk was lost entirely, it must rejoin as a new incarnation and catch up. With dynamic quorums, the old voter identity is replaced rather than reused, avoiding confusion.
| Failure | Client impact | Metadata writes | Typical recovery |
|---|---|---|---|
| Follower controller down | None | Continue | Restart and catch up |
| Active controller down | Brief pause in admin operations | Resume after election | Automatic election |
| Majority of controllers down | Existing traffic continues, no leadership changes | Blocked | Restore voters, never invent data |
| Broker down | Partitions fail over | Continue | Restart, catch up, unfence |
| Corrupt metadata directory on one node | None if quorum healthy | Continue | Reformat that node and rejoin |
If a majority of controllers are permanently lost, resist the urge to hand-edit files or force a new quorum from an outdated copy. Doing so can discard committed changes and cause brokers to disagree about the state of the cluster. Recover from the most complete surviving copy and follow the documented recovery procedure for your version.
If the office that keeps the official register is closed for a day, the shops in town can keep selling using what they already know. What they cannot do is open new shops or change owners until the office reopens.
17Security Considerations
The metadata log is the most sensitive data in the cluster. Protect it accordingly.
What makes it sensitive
Anyone able to write to the metadata log can create topics, grant themselves permissions, change credentials and reshape the whole cluster. Anyone able to read its files can see topic names, access rules and, depending on your setup, stored credential material. That is why access to controllers and their disks must be tightly limited.
Separate controller listener
Controllers use their own listener and port. Only brokers and other controllers should be able to reach it, enforced by firewalls or network policy.
Encrypt in transit
Use TLS on the controller listener so voter traffic, fetches and heartbeats cannot be read or altered on the wire.
Authenticate every peer
Require mutual TLS or SASL so only genuine brokers and controllers can register or vote.
Restrict cluster-level rights
Keep permissions for cluster-wide actions and super users to a very small set of principals.
Protect the disks
Use encrypted volumes and strict file permissions for the metadata directory and its snapshots and backups.
Log administrative actions
Record who created topics, changed access rules and altered settings, so surprises can be traced.
The master key cabinet in a building is kept in a locked room with a visitor log. Everyone benefits from the keys, but only a few people should be able to open the cabinet or copy a key.
Authorization data lives in the log
In KRaft, the standard authorizer keeps access control entries inside the metadata log rather than in an external store. That means every broker sees a consistent and current set of rules, and rule changes take effect quickly. It also means that a corrupt or tampered log could change who is allowed to do what, which is another reason to guard controller access.
Early in a cluster’s life, before any access rules exist, someone must be allowed to create them. Configure a small, well-audited set of super users for this purpose, and review that list regularly.
18Monitoring, Logging and Metrics
A healthy metadata log is quiet. Good monitoring tells you about trouble long before users feel it.
Questions your dashboards should answer
Is there exactly one active controller?
An active controller count of exactly one across the quorum is normal. Zero means no leader; more than one for any length of time is a serious alarm.
Is the leader stable?
Watch the current epoch and the rate of leader changes. Frequent elections point to networking, disk or resource problems.
Are commits fast?
Commit latency reflects how quickly a majority can store a record. Rising latency often means slow disks on a controller.
Is everyone keeping up?
Compare the last applied offset on each broker with the controller’s committed offset. Large or growing gaps signal lag.
Any load or apply errors?
Metadata load and apply error counts should stay at zero. Any increase deserves immediate investigation.
Is the controller busy?
Event queue time and processing time show whether the single controller thread is being overloaded.
Families of metrics to track
| Area | What to watch | Why it matters |
|---|---|---|
| Quorum health | Current leader, current epoch, high watermark, log end offset | Shows agreement and progress of the Raft group |
| Election activity | Election latency, number of new leaders | Reveals instability or flapping |
| Controller workload | Event queue time, event processing time | Detects a saturated controller thread |
| Cluster inventory | Active brokers, fenced brokers, topic count, partition count | Detects unexpected membership changes |
| Partition health | Offline partitions, preferred leader imbalance | Detects impact reaching client traffic |
| Metadata consumption | Last applied offset and record age on every node | Detects lag and stale brokers |
| Errors | Load errors and apply errors | Detects corrupted or unprocessable records |
| Disk | Free space and write latency on the metadata volume | Protects durability and commit speed |
Logs worth reading
Controller logs record elections, leadership changes, snapshot creation and quorum membership changes. Brokers log registration, fencing, metadata loading and failures to apply records. During any incident, gather the controller logs from all voters together and line them up by time, because the story of an election is spread across several machines.
Alert on: no active controller, more than one active controller, fenced brokers persisting, metadata errors above zero, applied-offset lag beyond a few seconds, and metadata disk usage or write latency above your comfort thresholds.
A hospital monitor does not tell you everything, but a steady heartbeat, blood pressure and oxygen level tell nurses at a glance whether to relax or rush over. Metadata metrics play the same role for your cluster.
19Inspecting the Log With Built-in Tools
Kafka ships tools that let you look inside the metadata log without guessing.
Quorum inspection tool
Describes the current quorum: who the leader is, the epoch, the high watermark, each voter’s replication progress and the observers that are following.
Metadata shell
Lets you browse a snapshot or a live view of the cluster like a file tree, exploring brokers, topics and configurations.
Log dump tool
Reads log segments and snapshot files and prints the records they contain, using a decoder that understands metadata record types.
Storage tool
Prepares the storage directories of a new node and stamps them with the cluster identifier before first start.
Features tool
Shows and changes the metadata version and other feature levels of the cluster.
Practical uses
Checking who is really in charge
After a network scare, ask the quorum tool for its status. If voters agree on the same leader and epoch and the lag is small, the quorum is healthy.
Finding when a change happened
By dumping records from the metadata log and searching for a topic or configuration key, you can see the exact offset and time when a setting was changed.
Offline investigations
Copy a snapshot to a safe workstation and open it in the metadata shell. You can answer questions about past cluster state without any risk to production.
Use these tools in read-only fashion on copies of files whenever possible. Never point a tool at the live directory of a running node and never edit segment files by hand.
20Advantages and Trade-offs
No design is free. A clear view of both sides helps you plan capacity and expectations.
Advantages
- One system to install, secure, monitor and upgrade instead of two
- Very fast controller failover because every voter already holds the full state
- Brokers follow one ordered log, so their views converge predictably
- Scales to far more partitions by replacing per-broker pushes with log reading
- Snapshots make restarts and new-broker onboarding quick
- Clear, replayable history of every change for debugging and audit
Disadvantages / Trade-offs
- Controllers become a critical tier that needs careful sizing and protection
- Loss of a majority of voters blocks all metadata changes
- A single-threaded controller can be a throughput ceiling under extreme administrative load
- Operators must learn Raft concepts such as epochs and quorums
- Upgrading and quorum changes demand disciplined procedures
- Memory on controllers and brokers grows with cluster size because the full image is held in memory
ZooKeeper era versus KRaft era
| Aspect | ZooKeeper-based Kafka | KRaft-based Kafka |
|---|---|---|
| Where metadata lives | In ZooKeeper nodes, with brokers caching copies | In the replicated metadata log on controllers |
| How brokers learn changes | Pushed by the controller through remote calls | Pulled by reading the log |
| New controller startup | Loads all state from ZooKeeper | Already has state, begins almost immediately |
| Systems to operate | Kafka and ZooKeeper | Kafka only |
| Security surface | Two security models to configure | One security model |
| Current status | Removed from current Kafka releases | The only supported mode |
21Capacity, Sizing and Performance Thinking
Metadata is small compared with message data, but its performance profile is unusual. Knowing what drives it prevents nasty surprises.
What grows with the cluster
The size of the metadata image is driven by counts, not by traffic. The more topics, partitions, replicas, configurations, access rules and registered brokers you have, the more memory the image takes and the more records a snapshot contains. Doubling the message volume changes almost nothing here. Doubling the partition count changes a great deal.
Partition count
Every partition needs records for its replicas and its in-sync set. This is usually the largest contributor to metadata size.
Replication factor
More replicas per partition means longer replica lists and more places where a change must be recorded.
Number of brokers
Each broker adds a registration, heartbeat traffic and another reader of the log, though observers do not affect commits.
Rate of change
Frequent topic creation, configuration edits or leadership changes raise the write rate on the log.
Security records
Large numbers of access rules, credentials or quotas add to both the log and the memory image.
Where latency comes from
The time to commit a metadata change is roughly the time for the leader to write the records, plus one network round trip to the fastest majority of followers, plus the time those followers take to write to disk. That means three things dominate: disk write latency on voters, network latency between voters, and how loaded the controller thread is. Improve those and commits become faster. Adding more brokers changes nothing here.
Getting three friends to sign a document takes as long as the second-fastest signer needs, plus the time to pass the pen around. It does not matter how many neighbors are waiting to read the finished document.
The cost of a burst
Some events cause a sudden flood of records. When a broker with thousands of partition leaderships dies, the controller must choose new leaders for all of them and record each one. When a large batch of topics is created by an automated tool, the same happens. A well-sized cluster absorbs these bursts in moments, but a cluster pushed close to its limits may show visible delays in administrative operations while it works through the queue.
| Resource | Controller need | Why |
|---|---|---|
| CPU | A few fast cores | Single event thread benefits from speed more than core count |
| Memory | Enough for the image plus headroom | The whole cluster picture is held in memory |
| Disk | Low-latency, reliable, modest size | Durable writes are on the commit path |
| Network | Low latency, reliable links to peers | Commits and elections depend on round trips |
Size controllers for the future partition count, not today’s. Memory and processing needs grow with counts, and resizing a critical quorum is easier when it is planned than when it is forced by an incident.
Partition counts and good hygiene
KRaft raises the practical ceiling on partitions, but it does not make unlimited partitions free. Each partition still costs memory, file handles, replication work and recovery time. A healthy practice is to review topics regularly, delete those that are abandoned and resist creating partitions “just in case”. The metadata log will thank you with smaller snapshots and quicker restarts.
22A Day in the Life of a Cluster: End-to-End Walkthrough
Let us tie every concept together by following one small cluster through an eventful day.
Our cluster has three dedicated controllers, named C1, C2 and C3, and four brokers. C1 is the active controller, and the current epoch is seven. The metadata log has been running for months, and each server holds a recent snapshot.
Morning: a new topic
A developer creates a topic for a new service. C1 validates it, appends a topic record and partition records, C2 and C3 fetch and store them, the majority commits, and the developer gets a success reply. The four brokers read the records and the chosen brokers create partition directories.
Late morning: a configuration change
An operator increases the retention of an important topic. One config record is committed. Every broker’s dynamic config handler picks it up from its new image within moments, with no restart.
Noon: a broker fails
Broker 3 loses power. Its heartbeats stop. After the session timeout, C1 records a fence for broker 3 and issues partition change records that move leadership of its partitions to other in-sync replicas. Clients get updated metadata from other brokers and carry on.
Afternoon: the broker returns
Broker 3 reboots and registers with a new incarnation. It is fenced at first. It loads its snapshot, reads the records it missed, and reports that it has caught up. C1 records an unfence, and broker 3 begins to rejoin as a follower for its old partitions and later takes back preferred leaderships.
Evening: the active controller crashes
C1 is lost in a hardware fault. C2 and C3 stop receiving responses. C3’s randomized timeout expires first. It moves to epoch eight, votes for itself and asks C2 for a vote. C2 confirms that C3’s log is as complete as its own and grants it. C3 becomes the leader within moments and announces itself.
Evening: brokers follow the new leader
Brokers see that their fetches to C1 fail, look up the quorum information, discover C3 as the new leader and continue reading from it. Any admin request sent to C1 is retried against C3 and succeeds.
Night: replacing C1
The team provisions a new controller machine. It joins as an observer, downloads a snapshot from C3, and catches up. The operator adds it as a voter and removes the dead C1 from the voter set. The quorum is back to three healthy voters, and no client noticed the entire episode.
sequenceDiagram
participant C1 as Controller C1 - epoch 7 leader
participant C2 as Controller C2
participant C3 as Controller C3
participant B as Brokers
Note over C1: Hardware fault
C2->>C1: Fetch times out
C3->>C1: Fetch times out
C3->>C3: Election timeout fires, epoch 8
C3->>C2: Request vote for epoch 8
C2-->>C3: Vote granted
C3->>C2: Begin epoch 8 as leader
B->>C3: Fetch committed records
C3-->>B: Records, epoch 8
What this day shows
Every event above is an ordinary change to a shared story. New topics, changed settings, failed brokers and dead controllers all became records or elections, and every server that read the committed story ended up with the same picture. There was no special recovery mode, no manual copying and no external database to reconcile. That is the practical beauty of treating the cluster’s brain as a log.
Whenever you face a puzzling Kafka behavior, ask three questions in order: what record should have been written, was it committed by a majority, and has every relevant broker applied it? Most metadata mysteries are answered by one of those three.
23Key Settings Explained in Words
You do not need to memorize every setting, but you should understand what each family of settings controls and why it exists.
Identity and roles
Process roles
Declares whether a process acts as a broker, a controller or both. This single choice decides which duties the process performs.
Node identifier
A unique number for each process. Controllers and brokers must never share an identifier within one cluster.
Cluster identifier
A unique label stamped into storage when a node is formatted. It stops a node from accidentally joining the wrong cluster.
Controller listener names
Names which network listener carries control traffic, keeping it apart from client traffic.
Quorum discovery
Two styles exist. The static style lists every voter explicitly, with identifier and address, in a voters setting. The dynamic style provides only a bootstrap list of addresses, and the true voter set is read from the log. Mixing the two styles by accident is a classic source of confusion, so pick one approach per cluster and document it clearly.
Timing and liveness
| Family | What it controls | Effect of making it shorter | Effect of making it longer |
|---|---|---|---|
| Election timeout | How long a candidate waits for votes before trying again | Faster recovery, but more risk of needless elections on slow networks | Calmer, but slower to recover |
| Fetch timeout | How long a follower waits for the leader before assuming it is gone | Quicker detection of failure, more false alarms during hiccups | Fewer false alarms, longer outages |
| Request timeout | How long to wait for a reply to any quorum request | Snappier retries | More patience on congested links |
| Broker heartbeat interval | How often a broker reports to the controller | Finer-grained tracking, slightly more traffic | Less traffic, slower detection |
| Broker session timeout | How long silence is tolerated before a broker is fenced | Fast failover, risk of fencing healthy but busy brokers | Fewer needless failovers, slower reaction to real failures |
Deciding how long to wait for a friend who is late. Wait two minutes and you may leave someone who was only stuck at a red light. Wait an hour and you waste everyone’s evening. Timeouts are the same trade between quick reaction and false alarms.
Storage and snapshots
Metadata log directory
Where the log segments and snapshots live. Placing it on a dedicated volume protects it from noisy neighbors.
Segment size and age
Decide how large or old a segment file grows before a new one starts, which affects how quickly old data can be removed.
Bytes between snapshots
A size threshold that triggers a new snapshot after enough new records accumulate.
Maximum snapshot interval
A time threshold that ensures a snapshot is taken even in quiet periods.
Metadata retention limits
Bound how much history older than the latest snapshot is kept, so disks do not fill.
Maximum idle interval
Makes the leader append a harmless no-op record if nothing else has been written for a while, keeping the committed point moving.
Timeouts interact with each other. Shortening several at once can produce flapping that is very hard to diagnose. Change a single value, observe for a full business cycle, and record the result before making the next change.
The default values were chosen for typical data-centre networks. Only move them when you have measured evidence, such as long-distance links between voters or unusually noisy infrastructure.
24How KRaft Compares With Other Coordination Approaches
Comparing KRaft with what came before, and with other systems, sharpens your understanding of its choices.
ZooKeeper’s approach
ZooKeeper is a general-purpose coordination service that stores small pieces of data in a tree of nodes and uses its own agreement protocol among an ensemble of servers. Kafka used it as an external database of cluster facts. ZooKeeper is well built, but as an outside system it had its own configuration, its own security, its own capacity limits and its own failure behaviors, all of which Kafka operators had to master in addition to Kafka.
What KRaft changes conceptually
What stays similar
- A small group of servers agrees on ordered changes by majority
- An elected leader handles all writes
- The system survives a minority of failures
- State is durable on disk on every voter
What changes
- The agreement engine is built into Kafka rather than being a separate product
- The data model is an event log with snapshots instead of a tree of nodes
- Brokers are followers of the log, not clients of a separate store
- Kafka’s own tooling, security and monitoring cover the whole system
| Question | External coordination service | Built-in replicated log |
|---|---|---|
| Who owns the truth? | The outside service | Kafka itself |
| How are changes spread? | Watches and pushed notifications | Ordered log that everyone reads |
| How is state rebuilt after failure? | Re-read from the store | Load snapshot and replay the tail |
| How many skill sets does the team need? | Two | One |
| Where can inconsistency creep in? | Between the store and each broker’s cached view | Only through lag, which is measurable |
Why an event log suits Kafka in particular
Kafka’s whole existence is built around the idea that a durable, ordered log is a powerful way to share state between many machines. The KRaft design applies this very idea to Kafka’s own state. This is sometimes described as the system eating its own cooking. The code that copies log data between machines was already battle-tested, so the team could extend it rather than write something brand new for metadata.
A bakery that sells bread to everyone in town but buys its own bread from a rival shop is in a curious position. Once it decides to bake its own bread for the staff too, ordering, quality and cost are all under its own roof. KRaft is Kafka using its own log for its own needs.
Relationship to other Raft-based systems
Key-value stores and service registries
Many popular stores use Raft to replicate a small, strongly consistent state that other software relies on. KRaft is similar in spirit, but its log and snapshots use Kafka’s own storage format and networking.
Distributed SQL databases
These use Raft per data range to replicate user data. Kafka does not do this for message data, which uses in-sync replica sets, but it does use Raft for the small and critical control state.
Other streaming platforms
Several streaming platforms also embed consensus rather than depending on an external service. The industry trend is clearly toward self-contained systems that are easier to deploy.
Kafka now uses two different agreement styles side by side: majority-based Raft for the small control log, and in-sync replica sets for high-volume message data. Each is chosen for what it does best, and recognizing which one is in play helps you reason about failures.
25Migrating From ZooKeeper to KRaft
Many organizations still have clusters born in the ZooKeeper era. The migration path shows how the metadata log takes over.
Kafka provides a supported migration approach that moves a live cluster from ZooKeeper to KRaft without downtime for clients. The idea is to introduce a KRaft controller quorum next to the existing ZooKeeper-based controller, let the quorum take control, copy the metadata across, and finally retire ZooKeeper.
Prepare
Upgrade the existing cluster to a release that supports migration, and confirm that all features you use are supported in KRaft mode.
Deploy the controller quorum
Start new dedicated controllers in migration mode, pointing at the same ZooKeeper ensemble and given the same cluster identifier.
Copy metadata
The quorum reads all cluster state from ZooKeeper and writes it into the new metadata log as records.
Roll brokers into KRaft mode
Restart brokers one at a time so they read metadata from the log instead of receiving pushes from the old controller.
Dual-write period
For a time, the quorum writes changes to both the log and ZooKeeper, so a rollback remains possible if a problem appears.
Finalize
When confidence is high, switch off migration mode. The metadata log becomes the sole source of truth and ZooKeeper can be decommissioned.
flowchart TB
A["ZooKeeper-based cluster"] --> B["Add KRaft controllers in migration mode"]
B --> C["Metadata copied into metadata log"]
C --> D["Brokers restarted in KRaft mode one by one"]
D --> E["Dual-write - rollback still possible"]
E --> F["Finalize - ZooKeeper retired"]
Moving a shop to a new address without closing. First set up the new premises, copy the stock records, let customers use both entrances for a while, and only lock the old door once you are sure nothing was left behind.
Before finalizing, rollback is straightforward. After finalizing, going back is no longer an option. Rehearse the migration on a staging cluster and hold the finalize step until your monitoring has been clean for a comfortable period.
26Design Patterns and Best Practices
These habits separate calm operations from nervous ones.
Dedicated controllers
Run controllers on their own machines. Message traffic and metadata duties then never compete for the same disks and processors.
Odd-sized quorum
Choose three or five voters. Adding a fourth or sixth does not improve fault tolerance and raises cost.
Spread across failure domains
Place voters in different racks or zones so that one physical failure cannot remove the majority. Three zones for three voters is the classic layout.
Fast, dedicated metadata disks
Use reliable, low-latency storage for the metadata directory. Commit speed depends on how fast a majority can persist records.
Low-latency networking between voters
Keep voters close enough that round trips are short. Elections and commits are sensitive to network delay and jitter.
Rolling changes, one at a time
Restart, upgrade or replace only one voter at a time and wait for it to rejoin and catch up before touching the next.
Infrastructure as code
Describe controllers, identifiers and quorum settings in version-controlled templates so the whole setup can be rebuilt reliably.
Backups of snapshots and configuration
Regularly copy snapshots and key configuration to safe storage so a catastrophic loss is recoverable from a known good point.
Schedule game days where you deliberately stop a controller, then the active leader, then isolate one zone. Confirm that alarms fire, that elections complete quickly and that the team knows the recovery steps.
Common mistakes to avoid
Ignoring the metadata log directory
Leaving it on a small shared volume that also holds other data can lead to a full disk and a stalled voter.
Raising the metadata version too early
Doing this in the same change as a software upgrade removes the safe rollback window.
Treating controllers as disposable
Although they are cheap in resources, they carry the cluster’s memory. Replace them with care, one at a time.
Forgetting to monitor lag on brokers
A broker that quietly falls behind can serve stale answers long before anyone complains.
27Anti-patterns to Avoid
Each of these looks convenient in the short term and causes pain in the long term.
Problem
Running production clusters with combined broker and controller nodes to save on servers.
Why It’s Harmful
A heavy message workload can starve the controller thread or disks, which delays elections and metadata commits. A single failing machine takes out both a data node and a voter at once, shrinking your fault tolerance in a way that is easy to overlook.
Correct Approach
Use dedicated controller nodes for production. Reserve combined mode for development and small experiments.
Problem
Choosing an even number of voters, such as two or four.
Why It’s Harmful
Two voters tolerate no failures at all, and four tolerate no more than three do. You pay more and gain nothing, and an evenly split network partition can leave neither side with a majority.
Correct Approach
Use three voters for most clusters and five where the availability requirement justifies the cost.
Problem
Placing all controllers in a single rack or availability zone.
Why It’s Harmful
One power, network or zone outage removes the entire quorum. The cluster loses its ability to change metadata even though many brokers survive.
Correct Approach
Spread voters across independent failure domains so any single domain loss leaves a majority intact.
Problem
Manually deleting or copying files inside the metadata directory to “fix” a node.
Why It’s Harmful
Segment, index and snapshot files are tightly related to Raft’s view of history. Manual edits can introduce a diverging or missing history, cause the node to reject or corrupt state, or in the worst case lead the quorum to lose committed records.
Correct Approach
Reformat the affected node and let it rejoin and catch up through the normal Raft and snapshot mechanisms, following the documented procedure.
Problem
Exposing the controller listener broadly on the network with no authentication.
Why It’s Harmful
Anyone reaching it could try to register as a broker, read cluster metadata or attempt administrative actions, endangering the whole cluster.
Correct Approach
Isolate the listener to the controller and broker networks and require encryption and mutual authentication.
Problem
Restarting several controllers at once during maintenance.
Why It’s Harmful
Taking down more than a minority of voters at once removes the majority, freezing metadata operations and forcing a stressful recovery.
Correct Approach
Change one voter at a time, verify it is healthy and caught up, then proceed to the next.
28Real-World and Industry Perspectives
The metadata log is not a lab curiosity. It runs the event streaming backbone of many companies.
Managed cloud Kafka services
Major managed offerings, including Amazon MSK and Confluent Cloud, run KRaft-based clusters for their customers. Their appeal is exactly the operational simplification: fewer moving parts to patch and secure behind the scenes.
Kubernetes operators
Operators such as Strimzi manage Kafka on Kubernetes, and dedicated controller node pools map naturally to the KRaft controller role. Rolling controller and broker pools separately mirrors the recommended upgrade order.
Very large partition counts
Platforms that host thousands of teams on shared clusters benefit from faster controller failover and quicker recovery, because the controller no longer reloads state from an outside store during an election.
Regulated industries
Banks and healthcare providers value having one security boundary and a replayable history of administrative changes, both of which simplify audits.
Edge and small deployments
Removing the need for a separate coordination service makes small clusters and edge sites far lighter to deploy and run.
Raft beyond Kafka
Kafka joins a family of systems that rely on Raft or similar consensus for their control state, including distributed key-value stores, service-discovery tools and distributed SQL databases. Engineers who learn the ideas in this tutorial will recognize them again and again: leaders, terms, majorities and replicated logs are the shared vocabulary of modern distributed systems.
29Frequently Asked Questions
No. The metadata log describes the structure and rules of the cluster. Consumer offsets are kept in a separate internal topic managed by the group coordinator.
Because metadata changes must be strictly ordered. One partition gives one global order that every server can replay to reach the same state.
No. Only controller voters vote. Brokers are observers that read the log but do not affect the majority.
Existing partitions with healthy leaders keep serving reads and writes for a while, but no leadership can change and no metadata operation can succeed. Restoring a majority of voters restores normal operation.
Yes technically, but replication of data partitions would be limited to the number of brokers, so you lose the durability benefits that come from multiple replicas. The controller count and broker count are independent choices.
It works and is fine for development, but it is not recommended for production because the two workloads compete for resources and failures affect both roles at once.
A compacted topic keeps the latest record for each key. The metadata log is cleaned using snapshots: a complete picture at a point in time is saved, and older segments are deleted once they are no longer needed.
Typically a matter of moments, dominated by the timeout used to detect that the leader is silent plus the election itself. It is much faster than the old model, since the new leader does not have to reload state from an external system.
Pull-based reading is simpler and more robust. A broker that misses something just asks again from where it left off, and the leader does not need to track or retry deliveries to hundreds of brokers.
With dynamic quorum support, yes. Voters can be added or removed one at a time through administrative commands. With a static quorum, changes require coordinated configuration updates and restarts.
Not if the quorum is healthy. Other voters hold the same history and snapshots. A node that loses its own snapshot or log can reformat and recover from the quorum. Backups are still wise for disaster scenarios.
Not directly. Message traffic does not pass through the metadata log. However, extremely large amounts of metadata, such as a huge number of partitions, increase memory use and the time needed for loading and administrative operations.
A stable, single active controller with steady epoch, together with brokers that are keeping up with the latest committed metadata offset. Those two signals reveal most trouble early.
No. Clients interact with brokers, and administrative requests are routed to the active controller. Ordinary applications never read or write the metadata log themselves, which protects the cluster’s most sensitive state from accidental damage.
Every controller in the quorum is a voter, meaning it stores the log and takes part in elections. Only one voter at a time is the leader, called the active controller, which is the sole server that appends new metadata records and answers administrative requests.
The identifier proves that all nodes belong to the same logical cluster. A node formatted for a different cluster is rejected, which prevents an accidental merge of two unrelated clusters that would mix incompatible histories.
No. Adding voters raises fault tolerance but slightly increases the work needed for each commit, because a bigger majority must confirm. Speed comes from fast disks, low network latency and a lightly loaded controller thread, not from a larger quorum.
30Summary and Key Takeaways
The KRaft metadata log turns Kafka’s brain into an ordinary, replicated, ordered log. A small quorum of controllers agrees on that log using a pull-based variant of Raft, the active controller is the only writer, and every broker follows the committed records to build an immutable in-memory picture of the cluster. Snapshots keep the log short, epochs keep leadership honest, and metadata versions keep upgrades safe. Understanding these few ideas lets you design, run and troubleshoot modern Kafka clusters with confidence.
Key Takeaways
- One ordered log is the source of truth — the single-partition metadata log records every topic, broker, setting, security rule and feature level of the cluster.
- Raft gives agreement — a change is committed only when a majority of voters have stored it, and epochs fence off any stale leader.
- Controllers write, brokers read — only the active controller appends records; brokers are observers that pull committed records and apply them through immutable images and deltas.
- Snapshots replace endless history — each node snapshots its own state, old segments are truncated, and lagging or new nodes catch up from a snapshot.
- Design for the quorum — use dedicated controllers, three or five voters, spread across failure domains, on fast reliable disks.
- Operate with discipline — change one voter at a time, upgrade controllers before brokers, and raise the metadata version only when the rollout is stable.
- Watch the right signals — a single stable active controller, healthy commit latency, no metadata errors and small applied-offset lag on every broker.