Repartitioning Internals in Kafka
What really happens when you add partitions, move replicas between brokers, or let Kafka Streams reshuffle your data by a new key. Explained from zero, with everyday pictures, clear diagrams, worked examples, and safe ways to do each job in production.
Imagine a busy post office that sorts letters into pigeonholes by street name. At first there are ten pigeonholes, and everything works well. As the town grows, the pigeonholes overflow, so the manager adds more. But now a problem appears: a letter for “Green Street” used to go into hole number four, and with the new number of holes, the sorting rule sends it to hole number seven. Some letters are in the old place and new letters are in the new place, and the clerks who expected all the Green Street letters in one spot are confused.
That small story is the heart of repartitioning in Apache Kafka. Kafka spreads each topic across pieces called partitions, and the way messages are assigned to partitions, the number of partitions, and the machines that hold them can all change over time. Each change has hidden effects on ordering, on consumers, on network traffic, and on data that is already stored.
The word “repartitioning” is used for three different jobs in the Kafka world: changing the number of partitions of a topic, moving partition copies between brokers, and reshuffling records by a new key inside Kafka Streams. This guide explains all three from the inside. You do not need any earlier knowledge of Kafka internals. We start with the basics and build up slowly to the details that matter in production.
Why Repartitioning Matters: The Big Picture
Before any technical words, let us see why anyone needs to repartition at all.
When you first create a Kafka topic, you must choose how many partitions it has. That choice is made on day one, when you know very little about the future. Months later, traffic may have grown ten times. Or one broker may be running out of disk while others are half empty. Or a stream processing job may need messages grouped by a different field than the one used when they were written. Each situation calls for a different kind of repartitioning.
Change the partition count
Add more partitions to a topic so more consumers can work in parallel. Changes where new messages with a given key land.
Move partition copies
Reassign replicas from one broker to another to balance load, add or retire machines, or change disk usage. The number of partitions stays the same.
Reshuffle by a new key
Inside Kafka Streams, write records back to Kafka grouped by a different key, so related records meet in the same place.
Think of a school library. Job 1 is adding more shelves so more students can browse at once. Job 2 is moving some books from an overloaded room to an emptier room without changing the number of shelves. Job 3 is re-sorting books by author instead of by subject, so a particular question can be answered from one shelf.
Why it is risky if done carelessly
Repartitioning touches the parts of Kafka that people rely on most: the order of messages for a key, the safety of copies, and the steady flow of data to consumers. A careless change can break ordering, overload the network, leave copies unsafe, or make a stream processing job give wrong answers. A careful change, on the other hand, is routine. The difference is knowing what happens inside.
Always ask first: which of the three jobs am I doing? Each has different tools, different risks, and different safe habits.
Kafka Basics You Need First
A short tour of the words we will use throughout.
Broker
A Kafka server that stores messages on disk and serves producers and consumers.
Topic
A named stream of messages, such as “orders” or “clicks”.
Partition
A slice of a topic. Each is an ordered list of messages.
Offset
The number of a message inside its partition, like a page number.
Replica
A copy of a partition kept on another broker.
Partition leader
The replica that serves all reads and writes for a partition. The others copy from it.
In-sync replicas
The copies that are fully caught up with the leader.
Consumer group
A team of consumers that share the partitions of a topic.
Producers write messages. Consumers read them. A message may carry a key, such as a customer number, and a value, which is the content. The key is the label that decides where the message goes.
A topic is a big filing cabinet. Each drawer is a partition. Every drawer has a main copy and spare copies in other buildings. A clerk writes the customer number on each paper, and the sorting rule uses that number to pick the drawer.
The brain of the cluster
One special part of the cluster, the controller, keeps the master list of which partitions exist and which brokers hold them. In modern Kafka, this job belongs to the KRaft controller group, which stores every change in an ordered metadata log. Whenever you change the number of partitions or move replicas, you are really asking the controller to update that master list, and the brokers then act on it.
What a Partition Really Is
A look inside one partition, so that moving or adding partitions makes sense.
A partition is not an abstract idea. On a broker, it is a real folder on disk. Inside that folder are files called segments. Each segment holds a range of messages in order. New messages are always added to the newest segment, the “active” one. When a segment gets big enough or old enough, Kafka closes it and starts a new one. Beside each segment are small index files that let Kafka jump quickly to a given offset or time.
A folder per partition replica
Each broker holds one folder for every partition replica it hosts, named after the topic and the partition number.
Segments are files of messages
Old segments are read-only. Only the newest one accepts writes.
Indexes speed up lookups
An offset index and a time index map positions to file locations.
Retention removes old segments
Whole segments are deleted when they pass the retention limit, or are cleaned by compaction.
A partition is like a diary made of notebooks. Only the newest notebook is open for writing. Old notebooks stay on the shelf and are thrown away when they are too old. A small index card at the front of each notebook tells you which page holds a given date.
Why this matters for repartitioning
Because a partition is just files, moving a partition means copying its files to another broker. That is why moving a large partition takes time and network. It also explains a key fact: Kafka cannot easily split or merge partitions. Each partition’s offsets are its own private numbering, and messages inside are already in a fixed order. Combining two partitions would require inventing a new order, which Kafka does not do.
Offsets are only meaningful inside one partition. Offset 500 in partition 0 and offset 500 in partition 1 are unrelated messages. Ordering guarantees exist only within a single partition.
How Keys Choose Partitions
The sorting rule inside the producer, and why it is the source of most repartitioning surprises.
When a producer sends a message with a key, it runs the key through a fixed mathematical function called a hash, which turns any text into a big number. Kafka’s standard hash is called murmur2. The producer then divides that number by the count of partitions and uses the remainder to choose the partition. This means the same key always goes to the same partition, as long as the partition count stays the same.
Take the key
For example, the customer number “C-1042”.
Turn it into a number
The hash function produces a large, seemingly random number, always the same for the same key.
Divide by the partition count
The remainder is between zero and one less than the count.
That remainder is the partition
All messages for “C-1042” go to the same partition, so their order is preserved.
A hotel gives each guest a room by taking the last digits of their booking number and finding the remainder after dividing by the number of floors. As long as the hotel has the same number of floors, a returning guest always gets the same floor.
What if there is no key?
Messages without a key have no reason to stay together, so the producer spreads them out. Modern producers use a “sticky” approach: they fill one batch for one partition, then switch to another. This creates larger batches, which are more efficient, while still balancing load over time. Because there is no key, repartitioning does not break any ordering promise for these messages, since none was made.
Custom partitioners
An application can supply its own rule for choosing partitions, for example to send big customers to dedicated partitions. That rule may depend on the partition count too, so anything you learn in this guide about counts and keys applies to your custom rule as well.
Different programming languages and client libraries may use different hash rules. If a Java producer and a producer written in another language use different hash functions, the same key can land in different partitions. Check that all producers of a topic use the same rule.
Ordering and Parallelism: The Two Promises
Partitions exist to give you two things, and repartitioning can disturb both.
| Promise | What it means | How partitions provide it |
|---|---|---|
| Ordering | Messages about the same thing are read in the order they were written | Same key goes to same partition, and a partition is strictly ordered |
| Parallelism | Many workers can share the load | Each partition can be read by one consumer in a group at a time |
Notice the tension. More partitions allow more parallel consumers, but each key lives in only one partition. Ordering is preserved per key, never across the whole topic. When you change the number of partitions, you may improve parallelism, but you also change which partition each key maps to, which can break ordering for a short time.
Think of a supermarket with several checkout lanes. More lanes let more customers pay at once (parallelism). But if one family always uses lane three, all their items are scanned in order. If the store reassigns families to lanes using a new rule, a family’s items may end up split across two lanes for a while.
The ceiling on consumers
Within one consumer group, a partition is read by exactly one consumer at a time. So a topic with six partitions can keep at most six consumers busy in one group. A seventh consumer would sit idle. This is the main reason teams add partitions: they need more workers than partitions allow.
The number of partitions is also the upper limit on your consumer parallelism forever, until you change it. Think about the largest number of consumers you may ever want, and leave some room.
Three Kinds of Repartitioning Compared
A side-by-side map before we go deep into each one.
| Question | Add partitions | Reassign replicas | Streams repartition topic |
|---|---|---|---|
| What changes? | Number of partitions in a topic | Which brokers hold each partition copy | Which partition each record lives in for processing |
| Does existing data move? | No, old data stays where it is | Yes, whole partition files are copied | Records are rewritten into a new internal topic |
| Does it affect key ordering? | Yes, for keys whose partition changes | No, partitions are unchanged | It creates the right key ordering for processing |
| Who starts it? | An operator or automation | An operator or a balancing tool | The Streams library automatically |
| Main risk | Broken ordering and stateful consumers | Network and disk overload | Extra topics and delay |
| Can it be undone? | No, partitions cannot be removed | Yes, move them back | Yes, change the topology carefully |
Building a bigger warehouse (more partitions), moving pallets between warehouses (reassigning replicas), and re-sorting boxes by destination on a conveyor belt (Streams repartition) are three different operations, even though all of them can be called “reorganizing the stock.”
The three jobs often interact. Adding partitions creates new replicas that then may need moving. Moving replicas can change leadership. A Streams job’s repartition topic depends on the partition counts of the topics it reads. Keep the whole picture in mind.
Choosing the Partition Count
The best repartitioning is the one you never need. Choose the count well from the start.
A simple sizing method
Estimate the target throughput
How many messages or megabytes per second do you expect at your busiest hour, plus room to grow for a year or two?
Measure what one partition handles
Test how fast one producer and one consumer can work on one partition with your real message sizes and processing work.
Divide
Divide the target by the producer speed and by the consumer speed. Take the larger of the two answers.
Add headroom
Multiply by two or three for growth, and round to a number with many factors, such as 12 or 24, so consumers divide evenly.
A restaurant owner counts how many meals one cook can prepare per hour, divides the expected busiest-hour orders by that number, and hires a few extra cooks for growth, but not fifty extra, because an overcrowded kitchen also becomes slow.
The costs of too many partitions
More open files and memory
Each partition replica means open files and buffers on a broker.
Slower leader elections
When a broker fails, every partition it led needs a new leader. More partitions means more work at that moment.
More replication traffic
Each follower fetches separately for each partition, adding request overhead.
Possible latency increase
A message must be copied to followers before it counts as committed, and busy brokers with thousands of partitions take longer.
Bigger cluster brain
The controller stores and shares more metadata. KRaft handles far more than the old design, but limits still exist.
More rebalance work
Groups with very many partitions take longer to reshuffle when members join or leave.
Do not create thousands of partitions “just in case.” Every partition has a running cost, and you can always add more later. Aim for a comfortable margin, not a huge one.
Adding Partitions: What Happens Step by Step
The first job, changing the count, seen from the moment you ask to the moment clients notice.
flowchart TD
A["Operator asks to raise partition count from 6 to 12"] --> B["Request reaches the active controller"]
B --> C{"New count larger than current count?"}
C -->|"No"| X["Request rejected - partitions cannot shrink"]
C -->|"Yes"| D["Controller picks brokers for the 6 new partitions - rack aware"]
D --> E["Controller writes new partition records to the metadata log"]
E --> F["Majority of controllers commit the records"]
F --> G["Brokers fetch the records and create empty partition folders"]
G --> H["Leaders are chosen and followers start copying - nothing to copy yet"]
H --> I["Producers refresh metadata and discover 12 partitions"]
I --> J["Consumer group notices the change and rebalances"]
J --> K["New keys spread over 12 partitions - old data stays in the first 6"]
The request is validated
The controller checks that the topic exists, that you are allowed to alter it, and that the new number is bigger than the current one.
Placement is decided
For each new partition, the controller chooses which brokers will hold the copies. It spreads them evenly and, when racks or zones are configured, across different racks.
The decision is recorded
The new partitions are written into the cluster’s metadata log and committed by a majority of controllers.
Brokers create folders
Each chosen broker creates an empty folder for its new partition replica, and one replica becomes the leader.
Clients discover the change
Producers and consumers learn about the new partitions the next time they refresh their view of the cluster.
A town council approves six new mailboxes at street corners. The post office assigns each one to a mail carrier, installs empty boxes, and updates the city map. Old letters stay in the old boxes. New letters may now be dropped in any of the twelve boxes.
The key point: no old data moves. The new partitions begin empty. Only messages written after the change use the new layout. This single fact causes almost every surprise in the rest of this guide.
Inside the Controller: Handling the Create-Partitions Request
A closer look at what the cluster’s brain does behind the scenes.
The request to add partitions is called CreatePartitions. Any broker can receive it, but only the active controller can act on it. In a cluster that uses KRaft, the active controller is the elected leader of the controller group. It is the only node allowed to add records to the metadata log, which is the single ordered list of every cluster change.
Forward to the leader
A broker that receives the request passes it to the active controller.
Build the assignment
The controller either uses the assignment you gave, or computes one that balances the number of partitions per broker and respects racks.
Write records
It adds one record per new partition, listing its replicas and its leader, and updates the topic’s partition count.
Commit and reply
After a majority of controllers store the records, the controller replies “done” to the requester.
Brokers pull the change
Every broker reads the new records from the metadata log and acts if it hosts a new replica.
Only the head librarian may write in the official catalog. A branch librarian who receives a request to add shelves carries it to the head librarian. Once the head librarian writes the new shelves into the catalog and the assistants sign it, every branch reads the catalog and builds its own shelves.
Manual placement
Administrators may supply a custom placement for the new partitions, for example to put them on newer brokers. The controller checks that the placement is valid: the right number of replicas, existing brokers, and no repeats. If it is valid, it simply records it. If not, it rejects the whole request, and nothing changes. This all-or-nothing behavior keeps the cluster consistent.
In the older ZooKeeper design, the same job was done by writing into ZooKeeper and having the controller notice. The steps are similar in spirit, but modern clusters keep everything in the metadata log, which makes the sequence clearer and faster.
What Producers and Consumers Notice
Clients learn about new partitions slowly and in a specific order. This gap creates most of the surprises.
Producers
A producer keeps a cached copy of the topic’s layout and refreshes it on a timer, by default every few minutes, or sooner if something goes wrong. Until it refreshes, it still uses the old partition count, so its keys still map to the old partitions. Different producers may refresh at different moments. During that window, two producers can send the same key to different partitions.
Consumers
A consumer group notices new partitions through its own metadata refresh. The group leader then asks the group coordinator to run a rebalance, which is a reshuffling of who reads which partition. During the rebalance, consumers pause briefly. Afterwards, the new partitions are assigned to members of the group.
| Actor | How it learns | What it does next | Risk during the gap |
|---|---|---|---|
| Producer with a key | Periodic metadata refresh | Starts hashing with the new count | Same key may reach two different partitions |
| Producer without a key | Periodic metadata refresh | Includes new partitions in its rotation | None for ordering, since none was promised |
| Consumer group | Periodic metadata refresh by the group leader | Triggers a rebalance and assigns new partitions | Brief pause, and a possible gap in reading the new partitions |
| Stateful consumer | Same as above | Receives keys it has no state for | Wrong counts or totals if it assumes keys never move |
When a city changes its postal codes, some post offices learn about it on the first day and others a week later. In between, the same address gets sorted in different ways by different offices.
Do not assume that “the command finished” means “everything now uses the new layout.” It only means the cluster accepted it. Clients follow later, one by one.
The Key Reshuffle Problem: A Worked Example
Let us watch six keys change partitions when the count goes from three to four.
To keep the numbers small, imagine that our hash function gave these six keys the numbers 12, 19, 25, 30, 41, and 58. The partition is the remainder after dividing by the partition count.
| Key | Hash number | Partition with 3 partitions | Partition with 4 partitions | Moved? |
|---|---|---|---|---|
| K1 | 12 | 0 | 0 | No |
| K2 | 19 | 1 | 3 | Yes |
| K3 | 25 | 1 | 1 | No |
| K4 | 30 | 0 | 2 | Yes |
| K5 | 41 | 2 | 1 | Yes |
| K6 | 58 | 1 | 2 | Yes |
Four of the six keys now go somewhere new. Consider K2: all its old messages (say, a customer’s earlier orders) sit in partition 1, but from now on its new messages arrive in partition 3. A consumer reading partition 3 sees K2’s newest orders but none of the earlier ones. Worse, a consumer reading partition 1 may still be processing old K2 messages while the new ones are already being handled in partition 3. The order across the two partitions is not defined.
Ordering can break
Old and new messages of one key sit in different partitions, read by different consumers, possibly at different speeds.
State can be lost
A consumer that keeps a running total per key in memory no longer sees all the messages for that key, so its totals become wrong.
Joins can fail
Two topics that used to line up partition by partition no longer do.
Compaction can keep duplicates
The same key may now exist in two partitions, and each keeps its own “latest” value.
A school changes from three houses to four and reassigns students by the new rule. A student who used to be in Red House with all their old records is now in Green House, but the old records remain in Red House’s cabinet. Neither house alone has the whole story.
The Doubling Trick: A Predictable Way to Grow
There is a neat mathematical habit that makes repartitioning easier to reason about.
When you double the partition count, something special happens with the remainder rule. A key that was in partition p can only end up in partition p (staying) or in partition p plus the old count (moving to a brand new partition). It never jumps to a different old partition. Let us see it with the same six keys, going from four to eight partitions.
| Key | Hash number | With 4 partitions | With 8 partitions | What happened |
|---|---|---|---|---|
| K1 | 12 | 0 | 4 | Moved from 0 to 4 (0 plus 4) |
| K2 | 19 | 3 | 3 | Stayed |
| K3 | 25 | 1 | 1 | Stayed |
| K4 | 30 | 2 | 6 | Moved from 2 to 6 (2 plus 4) |
| K5 | 41 | 1 | 1 | Stayed |
| K6 | 58 | 2 | 2 | Stayed |
On average, half of the keys stay and half move, and every moved key goes to exactly one predictable new partition. This is like splitting each old partition into two: the old one keeps some keys and the new one takes the rest. It does not fix the ordering problem, but it makes the problem easier to plan around, for example by knowing exactly which old partitions feed which new ones.
A classroom with a boys’ side and a girls’ side splits into two rooms. Each old room becomes two: one keeps some students and a new room takes the others. You always know where a student came from.
Plan growth in doublings
If you expect to grow, choose a starting count that is easy to double, such as 6, 12, 24, or 48. Then when growth comes, you double and enjoy this predictable pattern. Also, numbers with many factors let consumer groups share partitions evenly among different numbers of consumers.
Kafka itself does not use this property to move data or protect order. It is only a way of thinking that helps you plan a cutover. The system still treats the new partitions as empty and the old data as staying put.
Why You Cannot Reduce the Partition Count
Kafka only allows growth. Here is why shrinking is not offered.
Offsets are private
Each partition numbers its messages on its own. Merging two partitions would require renumbering, which would break every consumer’s saved position.
Order would be invented
Two partitions have no shared timeline. Interleaving them would create an order that never existed.
Deleting loses data
Simply removing partitions would throw away the messages inside them.
Consumers hold state
Saved positions and local state refer to specific partition numbers. Removing one breaks the meaning of those saves.
You cannot merge two diaries into one by tearing out the pages, because the pages already have their own dates and page numbers. If you want one diary, you must copy everything into a new book, carefully choosing an order.
What to do instead
If you truly need fewer partitions, the standard answer is to create a new topic with the count you want and move your data and your applications over to it. The next two chapters show how. It is more work than a single command, which is another reason to choose your count carefully at the start.
Some teams delete and recreate a topic to get a smaller count, forgetting that this erases the stored messages and the consumers’ saved positions. Only do this for topics whose contents can be safely lost.
The Copy-to-a-New-Topic Approach
The safest way to change a partition count while keeping every key together.
sequenceDiagram
participant PR as Producers
participant OT as Old Topic - 6 partitions
participant CP as Copier Job
participant NT as New Topic - 12 partitions
participant CO as Consumers
Note over OT,NT: New topic created with the desired partition count
PR->>OT: Keep writing as usual
CP->>OT: Read all messages in order per partition
CP->>NT: Write each message using the same key so keys spread over 12 partitions
Note over CP: Copier catches up to the end of the old topic
Note over PR,CO: Cutover window begins
PR->>NT: Producers switch to the new topic
CO->>NT: Consumers switch to the new topic after finishing the old one
Note over OT: Old topic retired after a safety period
Create the new topic
Use the new partition count, the same settings for retention and compaction, and the same security rules.
Run a copier
A simple consume-and-produce job, or a mirroring tool, reads the old topic and writes to the new one with the same keys.
Let it catch up
Wait until the copier is only a few seconds behind the end of the old topic.
Cut over carefully
Switch producers and consumers using one of the safe strategies in the next chapter.
Retire the old topic
After a safety period, stop the copier and delete the old topic.
Moving a whole shop to bigger premises: you fit out the new shop, copy the stock across while still selling in the old one, and choose a quiet evening to hand over the keys. The old shop stays for a few days in case something was forgotten.
Copy with the same keys and, if you need it, preserve the original timestamps. Then every consumer of the new topic sees the same timeline as before, just spread over more partitions.
Safe Cutover Strategies
Three ways to switch from the old topic to the new one without breaking key order.
| Strategy | How it works | Pros | Cons |
|---|---|---|---|
| Drain and switch | Stop the producers, let consumers finish the old topic, then start producers on the new topic and consumers on the new topic | Perfect key order, simple to reason about | A short pause in producing |
| Consumer-first switch | Move consumers to the new topic first, then producers, while the copier keeps the new topic up to date | Consumers never see a gap | Needs careful timing of the last copy |
| Dual-write | Producers write to both topics for a while, consumers switch, then the old writes stop | No pause and easy rollback | Risk of duplicates and complexity |
The drain and switch method in detail
Announce a quiet moment
Choose a low-traffic window.
Pause producers
Briefly stop writes to the old topic.
Confirm the copier is done
The new topic holds everything the old one held, and consumers of the old topic have processed it all.
Resume on the new topic
Restart producers and consumers pointing at the new topic. All new messages for a key now go to one partition.
At a train station changing platforms, the safest method is to stop boarding on the old platform, let the last passengers get off, and then start boarding on the new platform. A little waiting avoids a crowd running in both directions.
If your consumers are idempotent (repeating a message has no harm) and order across a cutover does not matter, you can use the simplest options and skip the pause. Choose the strictness that your business needs.
Compacted Topics and Repartitioning
Topics that keep only the latest value per key are especially sensitive to partition changes.
A compacted topic is a topic where Kafka eventually keeps only the newest message for each key. It works like a table: one row per key. Such topics are used for reference data, settings, and state that programs rebuild by reading from the start.
Compaction works inside each partition separately. If the same key lives in two partitions after you add partitions, each partition keeps its own newest value for that key. Now there are two “latest” values for one key, one old and one new. A program rebuilding the table by reading all partitions will see both, and which one it keeps depends on which partition it reads last. That can silently produce wrong data.
Duplicate keys across partitions
The old value sits in the old partition forever, until you delete the key with a special empty message in that partition.
Copy to a new topic
Build a new compacted topic. Compaction in the new topic keeps one value per key across a consistent partitioning.
Avoid adding partitions
Choose the count carefully at the start for compacted topics, since changing it later is costly.
An address book with one page per person. If the book is split into two volumes by a new rule and the old volume still has an old page for Asha, you now have two pages for her: one with her old phone number and one with her new one.
Of all topic types, compacted topics that are used as tables should almost never have partitions added. Plan a proper copy to a new topic instead.
Consumer Offsets and the New-Partition Gap
A subtle trap: consumers may skip messages that arrive in a new partition before they notice it.
Consumers save their progress as offsets, one per partition. A brand new partition has no saved offset. When a consumer is assigned it for the first time, it must decide where to begin. That decision is controlled by a setting with two common values: start from the earliest message, or start from the latest message. The default is to start from the latest.
Partitions are added
Producers with a fresh view begin writing into a new partition right away.
Consumers have not noticed yet
Their next metadata refresh may be minutes away.
The rebalance happens
The new partition is assigned to a consumer that has no saved position for it.
The consumer starts at the latest offset
Every message written to that partition before this moment is skipped, never read by this group.
A new post box is installed on your street. Letters start arriving at once, but you only begin checking it a few minutes later, and your rule is “read only new letters from now on.” The first letters that arrived are never read.
How to avoid losing messages
Start from earliest
For groups that must not miss data, set the reset behavior to earliest, so new partitions are read from their first message.
Speed up discovery
Shorten the metadata refresh interval for the change window, or restart consumers after adding partitions.
Consumers first, producers later
Where you control both, make sure consumers know the new partitions before producers begin using them.
Test this in a staging environment: add a partition, produce a message straight away, and check that your consumer group receives it. This one experiment finds many configuration mistakes.
Replica Reassignment: What It Is and Why You Need It
The second job: keeping the same partitions but changing which brokers hold their copies.
Over time, brokers become unevenly loaded. A few brokers may hold the busiest partitions, while others sit idle. You may add new machines that are empty, or you may need to retire old machines that must be emptied first. Or a broker’s disk is filling up faster than the others. In all these cases, the answer is the same: move some partition copies from one broker to another. This is called replica reassignment, or in daily speech, “reassigning partitions.”
Add new brokers
New brokers start empty. Kafka does not automatically move existing partitions onto them, so you must reassign.
Remove old brokers
Before shutting a broker down for good, move all its partitions away so no copy is lost.
Even out load
Spread busy partitions so no single broker’s disk, network, or processor is the bottleneck.
Change replication
Add or remove copies of a partition, for example to raise safety for an important topic.
Fix placement
Repair layouts where too many copies sit in the same zone or rack.
Move between disks
Shift a partition from a full disk to an emptier one on the same broker.
A delivery company has several warehouses. When a new warehouse opens, boxes do not fly there on their own; managers must decide which boxes to move, plan the trucks, and make sure no order is ever left without a copy of its goods along the way.
Reassignment never changes the number of partitions or the keys’ partitions. Ordering is not affected. Only the physical location of the copies changes.
Architecture of a Reassignment
The trick is to add first, wait, and only then remove.
flowchart TB
OP["Operator submits a plan - move partition 3 from brokers 1,2,3 to brokers 2,3,4"]
CT["Active controller records: adding replica on broker 4, removing replica on broker 1"]
ML[("Metadata log")]
subgraph BRK["Brokers"]
B1["Broker 1 - old replica - LEADER"]
B2["Broker 2 - follower - stays"]
B3["Broker 3 - follower - stays"]
B4["Broker 4 - NEW replica"]
end
OP --> CT
CT --> ML
ML -.->|"brokers read the plan"| BRK
B4 -->|"1 fetches all data from the leader"| B1
B2 -->|"copies as usual"| B1
B3 -->|"copies as usual"| B1
B4 -->|"2 joins the in-sync list when caught up"| CT
CT -->|"3 chooses a new leader if the old one leaves"| B2
CT -->|"4 removes the old replica and deletes its files"| B1
Plan submitted
You describe the desired final list of brokers for each partition you want to move.
Temporary bigger replica set
The controller records the union of old and new replicas, so the partition temporarily has extra copies. The new ones are marked as “adding” and the ones to leave as “removing.”
New copies catch up
The new replicas act like ordinary followers and fetch everything from the leader, starting at the beginning of the partition.
They join the in-sync list
When a new replica has caught up, the leader adds it to the list of in-sync replicas.
Leadership adjusts
If the current leader is on a leaving broker, the controller picks a new leader from the final set.
Old copies are removed
The leaving replicas are stopped and their files are deleted. The reassignment is complete.
When moving a family’s valuables to a new safe, you never empty the old safe first. You copy everything into the new safe, check that it is complete, and only then clear the old one. At no time is there fewer than the full set of copies.
The Reassignment State Machine and Where It Is Stored
Because reassignments take a long time, their state must survive failures.
A big reassignment can run for hours or days. During that time, brokers may restart, and even the active controller may change. So the plan and its progress cannot live only in someone’s memory. In modern Kafka, the state is stored in the cluster’s metadata log: each partition record carries the current replica list plus the “adding” and “removing” lists. Anyone who reads the log sees exactly what is in progress.
stateDiagram-v2
[*] --> Stable
Stable --> Reassigning : plan accepted - adding and removing lists set
Reassigning --> Reassigning : new replicas still catching up
Reassigning --> Finishing : all adding replicas are in sync
Finishing --> Stable : removing replicas deleted and lists cleared
Reassigning --> Stable : reassignment cancelled - adding replicas dropped
Work resumes
The broker reads the log, sees it still hosts an “adding” replica, and continues fetching from where it stopped.
New leader continues
The new active controller reads the same lists in the log and carries on watching for replicas to catch up.
Return to the start
The controller removes the adding replicas and keeps the original ones, provided the move is not finished.
A construction project has a public progress board on the site wall. Any new supervisor arriving in the middle of the work reads the board and knows exactly which rooms are done, which are in progress, and which are still to start.
How the Data Actually Moves
There is no special copy tool. A new replica simply behaves like a very late follower.
Kafka reuses the normal replication machinery. The new replica sends fetch requests to the partition leader, starting at the earliest offset still on disk. The leader answers by reading its segments and sending batches of messages. The new replica writes them to its own disk and asks for more. Once it reaches the end and keeps up with new writes, it is considered caught up.
What the leader has to do
Read old segments
Historic data is often not in memory, so it comes from disk. This is extra disk work on the leader.
Send over the network
A large partition can mean hundreds of gigabytes leaving the leader’s network card.
Keep serving normal work
Producers and consumers still need the leader. The copy work competes with them for disk and network.
| Resource | Who pays | Symptom if overloaded |
|---|---|---|
| Disk reads | The leader (and the broker serving the copy) | Consumers lag, latency rises |
| Network out | The leader | Producers see slower acknowledgments |
| Network in and disk writes | The new replica’s broker | That broker’s own partitions slow down |
| Page cache | The leader | Old data pushes recent data out of memory, hurting fast readers |
Copying a huge library to a new building means a truck loads books from the old shelves at the same time as readers still borrow books. If the truck takes over the doorway, readers wait outside.
Reading old data for the copy can push fresh data out of the operating system’s memory cache. Consumers who normally read fresh data from memory then start reading from disk, which is slower. This is the hidden cost of large moves.
Throttling: Keeping the Move Polite
A speed limit protects everyday traffic while the move is running.
Kafka lets you set a maximum data rate for the replication that belongs to a reassignment. This limit is applied to the leaders that send the data and to the new replicas that receive it. Only the moving replicas are limited, so normal replication of other partitions continues at full speed.
Choose a rate
Pick a number that leaves plenty of room for regular traffic. A safe starting point is a modest share of the network capacity.
Apply it with the plan
The tool sets broker-level rate limits and marks the topic’s moving replicas as throttled.
Watch and adjust
If regular latency is fine, you may raise the rate a little. If consumers lag, lower it.
Remove the limit when done
After the move finishes, run the verification step so the throttle settings are cleared.
A water company, while filling a new tank, limits how fast it draws from the main so the neighborhood taps do not run dry. When the tank is full, the limit is lifted.
A very common mistake is forgetting to clear the throttle after the move. Leftover limits can silently slow the replication of those partitions during later failures, when speed matters most. Always run the verify step and confirm the limits are gone.
Too tight a limit
If the throttle is lower than the rate at which new data arrives in a partition, the new replica can never catch up and the move never finishes. Compare the limit with the write rate of the partitions you are moving.
Running a Reassignment Safely: The Phases
A checklist that turns a risky operation into a routine.
Check cluster health
No offline partitions, no lingering under-replicated partitions, and free disk space on the target brokers.
Generate a proposal
The tool can propose a layout for a list of topics and a list of target brokers. Review it carefully. It is a suggestion, not an order.
Save the current layout
Keep a copy of the present assignment. It is your way back.
Start small
Move a few small partitions first to check the rate, the effect on latency, and the tool’s behavior.
Execute in batches with a throttle
Do not move everything at once. Batches limit risk and let you stop between them.
Watch the metrics
Track under-replicated partitions, replication rate, disk use, network use, and consumer lag.
Verify and clean up
Confirm every move completed, clear throttles, and check that leadership is balanced.
Cancel if needed
If something goes wrong, cancel the running moves. The originals are still in place until each move is finished.
Moving house in stages: first a few boxes to test the route, then the furniture in a few loads, checking each time that nothing is broken, and a final walk-through before handing back the keys.
Schedule big moves for off-peak hours, and never at the same time as broker upgrades, migrations, or other big changes. One risky thing at a time.
Leaders After the Move: Balance and Preferred Leaders
Moving copies does not automatically balance leadership. A second look is needed.
The first broker in a partition’s replica list is called the preferred leader. Kafka tries to spread preferred leaders evenly across brokers, because the leader does more work than followers: it handles all reads and writes. When you reassign replicas, the order of the list matters. A list that puts the same broker first for many partitions makes that broker the preferred leader of them all.
Leaders do more work
All client traffic goes to leaders. A broker with too many leaders becomes the hot spot.
Periodic rebalancing
By default, the controller checks now and then whether leaders match the preferred ones and moves them back if the imbalance is large enough.
Preferred leader election
An administrator can ask for it directly right after a move, instead of waiting for the next check.
After a restructure, new team members are in place, but the meeting chairs are still all sitting with the same few people. Someone must hand out the chair roles so the load is shared.
Order your replica lists on purpose
When writing a plan by hand, do not just list brokers in numeric order for every partition. Rotate the first broker so that each broker leads about the same number of partitions. Tools that generate proposals usually do this for you.
Moving Between Disks on the Same Broker
Sometimes the problem is one full disk, not one full machine.
Many brokers have several data disks. A partition lives on one of them. If one disk fills up while others have space, you can ask the broker to move that partition to another disk on the same machine. This is called moving between log directories.
Ask for the move
The plan names the target disk for a specific replica on a specific broker.
A “future” copy is created
The broker starts building a second copy of the partition on the target disk, and keeps appending new messages to both copies.
The copy catches up
When the future copy has all the data, the broker swaps it in atomically.
The old copy is deleted
The space on the old disk is released.
You move a file cabinet from a cramped room to a bigger room in the same building. You place a new cabinet, keep both updated for a moment, and then remove the old one. The rest of the office never notices.
This kind of move uses disk and internal bus bandwidth but not the network between brokers. It is often gentler than a move between brokers, but it still needs free space on the target disk for the duration.
Automation: Cruise Control and Self-Balancing
Doing all this by hand does not scale, so large operators use automatic balancers.
A balancer is a program that watches how busy each broker is, decides which partitions to move where to even out the load, and carries out the moves gently with a throttle. The best-known open-source one is Cruise Control, created at LinkedIn. Commercial Kafka platforms offer similar built-in features, and operators for Kubernetes such as Strimzi integrate Cruise Control.
Watch
It collects metrics about disk, network, processor use, and partition sizes for every broker.
Model
It builds a picture of the cluster’s load, and of how the load would look after each possible move.
Propose
Using goals, such as balanced disk, balanced network, rack safety, and even leader counts, it proposes a set of moves.
Execute
It runs the moves in small batches with throttling and can stop if the cluster becomes unhealthy.
Heal
Some setups also react automatically to broker failures or newly added brokers.
A traffic control center watches all roads through cameras, then changes signals and diverts vehicles to relieve jams. A human could do this for a small town, but a big city needs a system.
Even with automation, review the balancer’s proposals at first, and start with small batches. Let it earn your trust step by step before allowing fully automatic runs.
Kafka Streams Repartition Topics: The Third Job
Inside stream processing, repartitioning means something different, and happens automatically.
Kafka Streams is a library for building programs that read from topics, transform the data, and write results. Many operations, such as counting per customer or joining two streams, only work correctly if all records with the same key are processed by the same worker. If your data is keyed by order number, but you want to count by customer, the records for one customer are scattered across many partitions. Streams solves this by writing all records again into a special internal topic, using the customer as the new key. This is the repartition topic.
flowchart LR
IN["Input topic - keyed by order number"] --> S1["Sub-topology 1 - read and filter"]
S1 --> SK["selectKey - customer becomes the new key"]
SK --> RT[("Internal repartition topic - keyed by customer")]
RT --> S2["Sub-topology 2 - count per customer"]
S2 --> ST[("Local state store")]
S2 --> CL[("Changelog topic - backs up the state")]
S2 --> OUT["Output topic - counts per customer"]
You change the key
By using an operation such as selecting a new key or grouping by a different field, you tell Streams that keys have changed.
Streams flags the stream
It remembers that this stream “requires repartitioning” but does nothing yet.
A key-based operation appears
When you then count, aggregate, or join, Streams inserts the internal topic.
The topology is split in two
One part writes to the internal topic. The next part reads from it. Each part runs as separate tasks.
Related records meet
Because the new key decides the partition, all records for one customer now arrive at the same task.
A mail sorting center gets parcels sorted by sender. To deliver by receiver, it must re-sort everything onto a new belt organized by receiver. That extra belt is the repartition topic.
Co-Partitioning and Joins
Joins are the strictest users of partition rules.
To join two streams by key, Streams needs matching records from both sides to be processed together. This only works if the two topics are co-partitioned: they have the same number of partitions and use the same rule to assign keys to partitions. Then partition 3 of the first topic and partition 3 of the second topic hold the same keys, and one task can handle both.
| Requirement | Why it matters | What Streams does |
|---|---|---|
| Same partition count | Otherwise the same key maps to different partition numbers | Checks at startup and reports an error if they differ |
| Same partitioning rule | Otherwise keys land in different partitions even with equal counts | Trusts that you used the default rule or the same custom rule |
| Keys of the same type and format | Otherwise equal keys hash differently | Relies on matching serializers |
Ways to satisfy co-partitioning
Plan counts in advance
Create related topics with the same partition count from the start.
Repartition explicitly
Write one side through a repartition step with the count that matches the other side.
Use a global table
A global table copies all data to every worker, so no co-partitioning is needed. It suits small reference data.
Two exam boards mark papers in matching numbered rooms so that a student’s written paper and practical paper are marked in the same room. If one board has eight rooms and the other has ten, the two papers of one student end up in different places.
Adding partitions to one input topic of a running join breaks co-partitioning and the alignment of the application’s saved state. The usual cure is to plan a new topic and reset and reprocess the application, not to just add partitions.
Naming, Optimizing, and Cleaning Repartition Topics
Small habits that prevent big headaches in stream processing jobs.
Name your operations
Unnamed steps get generated names with running numbers. Add or remove a step, and the numbers shift, so the internal topic names change and the job loses its saved state. Give important steps explicit names.
Avoid needless key changes
If you only change values, use the value-only operations. Operations that can change keys make Streams assume a repartition may be needed.
Turn on topology optimization
When the same re-keyed stream feeds several operations, Streams can merge the duplicate internal topics into one, saving storage and time. Enable it deliberately and test, since changing it changes the topology.
Set the partition count on purpose
By default the internal topic copies its count from the upstream topics. You can set it explicitly to give downstream work more parallelism.
Let Streams clean up
Streams removes records from repartition topics after they have been processed, so these topics do not grow without limit.
Labeling boxes clearly during a house move lets you find them after the movers rearrange the truck. Boxes labeled “box 17” only work if the numbering never changes.
Print or describe your topology and read it. Every internal topic listed is extra storage and extra delay. If you did not expect a repartition topic, look for a hidden key change.
Placement Rules: Racks, Zones, and Where Copies Should Live
A move is only good if the new layout is also safe.
Every broker can be told which rack or availability zone it sits in. A rack is a physical shelf of machines that shares power and network switches. A zone is a similar idea in the cloud: a separate building or section of a data center. If all three copies of a partition sit in one rack, a single power failure removes the whole partition. So Kafka tries to spread copies across different racks when it creates topics.
Rack-aware by default
When brokers declare their racks, new topics spread copies across them, one per rack when possible.
You must check
A hand-written reassignment plan can silently put two copies in one rack. Kafka accepts it, because it cannot know your intentions.
Usually aware
Proposals from the built-in generator and from balancers normally respect rack information, but always read the result.
Closest copy
Consumers can be allowed to read from a nearby follower, which saves cross-zone network costs, when placement is thoughtful.
Keeping three copies of an important document in three different buildings protects you from a fire. Keeping three copies in one drawer does not, even though you technically have three copies.
Retiring a broker in a small rack can leave that rack empty or overloaded. Before draining a broker, count how many brokers each rack will still have, and make sure the number of racks is at least the replication factor.
Checking a plan before running it
Count copies per rack
For each partition in the plan, confirm that its copies are in different racks.
Count leaders per broker
Confirm the first broker of each list is spread evenly.
Estimate disk after the move
Add up the size of the partitions each broker will hold and compare with its disk size, leaving generous free space.
Estimate traffic after the move
Check that no broker ends up with the busiest partitions all together.
A Worked Sizing Example: Choosing the Count
Numbers make the rule of thumb concrete.
Imagine a topic that must handle 300 megabytes per second of incoming data in a year. A test shows that one partition comfortably takes about 15 megabytes per second on the producer side, and one consumer instance can process about 10 megabytes per second. Which count do we need?
| Question | Calculation | Result |
|---|---|---|
| Partitions needed for producers | 300 divided by 15 | 20 |
| Partitions needed for consumers | 300 divided by 10 | 30 |
| Take the larger | Maximum of 20 and 30 | 30 |
| Add headroom for growth and skew | Multiply by about one and a half | 45 |
| Round to a friendly number | Pick a number with many divisors | 48 |
With 48 partitions, the readers can run as 6, 8, 12, 16, 24, or 48 instances with every instance getting an equal share. A count like 47 would give uneven shares for almost any group size. That is the reason for choosing a friendly number.
A school planning classrooms does not choose 47 desks per room. It picks a number that divides evenly into teams of two, three, four, or six, so any group activity works without leftovers.
Checking the cost side
With a replication factor of 3, 48 partitions means 144 copies for that topic across the cluster. If there are 6 brokers, that is 24 copies per broker for this one topic. If the whole cluster hosts hundreds of topics, the total per broker can grow into thousands, which is fine on modern versions but still worth watching. Always add up all topics, not one at a time.
Skew matters as much as totals. If a handful of keys produce most of the traffic, those keys will always land in a few partitions, and no partition count will fix it. Fix the key choice instead.
When Things Go Wrong During Repartitioning
Failures are normal. What matters is knowing what each one does to your data.
| What fails | During which job | What happens | What you do |
|---|---|---|---|
| A broker restarts | Replica reassignment | The new copy on it pauses, then resumes from where it stopped after the broker returns | Wait, and watch that the move continues |
| The leader of a moving partition fails | Replica reassignment | Another in-sync copy becomes leader. The new copies start fetching from the new leader | Check that in-sync counts recover |
| The target broker runs out of disk | Replica reassignment | The new copy cannot be written and the move stalls or fails | Cancel, free space or choose another target, then retry |
| The active controller changes | Any | The next controller reads the saved plan and continues | Nothing, apart from watching |
| Client sends the create-partitions request twice | Adding partitions | The second request asks for a count that is not larger than the current one and is refused | Nothing, it is safe |
| Producer has old metadata after adding partitions | Adding partitions | It keeps using the old count until it refreshes, so new partitions get no traffic for a short time | Wait for the refresh, or restart |
| Streams job crashes after the repartition write | Streams repartition | Records already in the internal topic stay there and processing resumes from the saved bookmark | Nothing, the design covers it |
Think of an airport that keeps a written log of every plan. If a supervisor collapses in the middle of a shift, the next supervisor reads the log and continues exactly where the last one stopped.
The reason moves are so safe is the order of steps: a new copy is added, filled, and proven in sync before an old copy is removed. Failing in the middle leaves you with more copies than needed, never fewer.
The one dangerous combination
The riskiest time to move partitions is when the cluster is already unhealthy: some brokers down, some partitions with too few in-sync copies. Extra copy traffic can push the weak part of the cluster over the edge. This is why every checklist starts with “check the cluster health first.”
Performance: What Repartitioning Costs
Each of the three jobs spends different resources.
Cheap right now, costly later
The request itself is tiny. The costs show up as more files, more memory for indexes, more replication traffic, more client connections, and longer recovery after a broker failure.
Expensive right now
Large volumes of data are read, sent, and written. Disk, network, and memory cache are all affected until the move ends.
A steady tax
Every record that passes a key change is written and read one extra time, plus replicated. That doubles some of the traffic and adds delay for each record.
How long will a move take?
A rough estimate is the amount of data to move divided by the throttle rate. If you must move 2,000 gigabytes and the throttle allows about 100 megabytes per second, that is around 20,000 seconds, or a bit more than five and a half hours. Real moves take longer because the throttle is shared by all moving partitions, new data keeps arriving, and small partitions still need time to set up.
Filling a swimming pool through a garden hose is predictable if you know the pool size and the hose flow. A wider hose is quicker, but it also lowers the pressure in the whole house.
| Bottleneck | How it shows up | What helps |
|---|---|---|
| Network on the leader | Producer acknowledgments slow down | Lower throttle, spread the load across many leaders |
| Disk on the leader | Consumers of older data lag | Smaller batches of partitions, off-peak timing |
| Disk on the target | New copy catches up slowly | Faster disks or fewer parallel moves onto that broker |
| Page cache pollution | Fast consumers suddenly read from disk | Throttle gently and avoid huge moves during busy hours |
| Controller work | Slow metadata updates when thousands of moves run at once | Batches and limits on concurrent moves |
Measure before and after. Note your normal produce latency, fetch latency, and consumer lag before you start, so you can tell whether the move is hurting you or the cluster is simply having a busy day.
Advantages, Disadvantages, and Trade-offs
Every repartitioning choice buys something and costs something.
What you gain
- More partitions raise the ceiling on consumer parallelism and write throughput
- Reassignment lets you grow, shrink, and heal a cluster without downtime
- Balanced leaders and disks remove hot spots
- Streams repartition topics make correct per-key work possible on any key
- New topics with the right count fix old planning mistakes cleanly
What it costs
- Adding partitions cannot be undone and changes where keys go
- Per-key ordering can be briefly broken across the change
- Reassignment uses large amounts of disk and network
- Too many partitions slow recovery and use memory
- Streams repartition topics add storage, delay, and complexity
| Approach | Best when | Main risk | Reversible? |
|---|---|---|---|
| Add partitions in place | Keys do not matter, or a short ordering break is acceptable | Key reshuffle and ordering gap | No |
| Copy into a new topic | Keys and ordering matter, or you need fewer partitions | Cutover complexity and double storage | Yes, you can keep the old topic until sure |
| Reassign replicas | Balance, growth, or retirement of brokers | Resource pressure while copying | Yes, until the move completes |
| Balancer automation | Big clusters with frequent change | Trusting proposals too quickly | Yes, by stopping and reverting |
| Streams repartition topic | Grouping or joining on a new key | Extra latency and storage | Depends on redesign of the topology |
Adding checkout lanes to a shop is quick and cannot easily be taken back. Reorganizing which staff work at which shop is slow and needs care but can be changed later. Both are useful, and they solve different problems.
Security Around Repartitioning
These are powerful administrative actions, and they should be protected like keys to the building.
Changing the shape of a cluster can cause outages, data exposure, or extra bills. So Kafka lets you control who may do each action, through access rules called ACLs (access control lists), together with authentication that proves who someone is.
| Action | Permission needed | Why it is sensitive |
|---|---|---|
| Add partitions to a topic | Alter permission on that topic | Irreversible and changes key placement |
| Start or cancel a reassignment | Alter permission on the cluster | Can overload brokers and move data around |
| See reassignments in progress | Describe permission on the cluster | Reveals the layout of the cluster |
| Move a replica to another disk | Cluster-level administration rights | Touches disk layout directly |
| Create Streams internal topics | Create and write permission for the application’s internal names | The app needs to make and use topics named after its identifier |
Authenticate everyone
Use encrypted connections and real identities, so that every admin action can be traced to a person or tool.
Separate roles
Application accounts should not have cluster administration rights. Keep them for a small operations group and automation tools.
Protect data in motion
Copy traffic between brokers crosses the network. Encrypt it, as you do for normal replication.
Log administrative calls
Keep records of who changed partition counts and who started moves, and when.
Mind the new topic
A topic created by copying must get the same access rules as the original, or you accidentally expose or lock the data.
Guard the automation
A balancer holds admin rights over the whole cluster, so secure its account and its web interface carefully.
In a warehouse, only the manager may authorize moving pallets between buildings, and every move is signed. Ordinary workers can pick and pack, but they cannot reorganize the storage plan.
Access rules are attached to topic names. When you move traffic to a new topic name, the rules for the old name do not follow. Prepare the permissions before the cutover, not after the first error message.
Monitoring, Logging, and Metrics
What to watch before, during, and after any repartitioning work.
Exact metric names vary by version and by the monitoring tool you use, so treat the table as a guide to the ideas. Three questions guide everything: Is the cluster healthy? Is the move progressing? Are users affected?
| What to watch | Why | Warning sign |
|---|---|---|
| Under-replicated partitions | Shows copies that are behind. Moves create some naturally | The number grows and never falls |
| Partitions under the minimum in-sync count | Writes with strong acknowledgments fail here | Any non-zero value that persists |
| Offline partitions | No leader available | Anything above zero |
| Leader count per broker | Shows balance of client work | One broker far above the others |
| Bytes in and out per broker | Shows network pressure from copying | Close to the network card limit |
| Disk usage per broker and per disk | Targets can fill up during a move | Above roughly three-quarters full |
| Produce and fetch request time | Shows if users feel the move | Rising well above your normal baseline |
| Consumer lag per partition | Shows whether readers keep up | Lag concentrated on new or moving partitions |
| Bytes per partition | Shows skew after adding partitions or hot keys | New partitions far emptier than old ones |
| Reassignments in progress | Shows the status of every move | A move that has not advanced for hours |
| Streams internal topic size and lag | Shows the cost and health of repartition steps | Repartition topic lag growing steadily |
Logs worth reading
Controller log
Records the acceptance of partition changes and reassignment steps.
Broker logs
Show new partitions being created and replicas starting to fetch, or failing.
Client logs
Show metadata refreshes, group rebalances, and errors about unknown partitions.
Streams application logs
Report task assignments and any complaint about mismatched partition counts.
During a road resurfacing project, engineers watch traffic counters, complaint lines, and the work schedule at once. If only the work schedule is watched, drivers can be stuck in jams unnoticed.
Best Practices and Design Patterns
Habits that make repartitioning boring, which is exactly what you want.
Plan for growth at creation
Choose a partition count with headroom, often a number with many divisors so that later consumer counts divide evenly.
Double, never nudge
If you must add, doubling keeps most keys in a predictable place. Small increments reshuffle more.
Key with intent
Choose keys that spread well and match how you process. Wrong keys are the source of most repartitioning trouble.
Blue-green topics
Create the new topic beside the old, run both, switch, and retire the old one later.
Move in batches
Small groups of partitions with a throttle, checked at each step.
Rehearse first
Practice the exact steps on a test cluster with similar shape, and time them.
Automate with review
Use a balancer, but read its plans and start with dry runs.
Name Streams operators
Explicit names keep internal topics stable between deployments.
| Practice | Reason |
|---|---|
| Keep free disk space on every broker | New copies need room, and old copies are removed only at the end |
| Spread copies over racks or zones | A whole rack failing should not remove every copy |
| Announce the change to client teams | They may need to expect a rebalance or ordering gap |
| Set consumer reset behavior deliberately | Prevents the loss of first messages in new partitions |
| Record the layout before and after | Gives you an undo plan and an audit trail |
| Remove throttles when done | Leftover limits slow recovery later |
| Do one big change at a time | When something breaks, you know the cause |
A good moving company labels boxes, packs the truck in a planned order, and does a walk-through afterward. None of this is exciting, and all of it prevents lost furniture.
Anti-Patterns to Avoid
Four popular mistakes and the better ways to work.
What people do
They add partitions to a keyed topic in the middle of the day, without telling anyone, because a consumer group needs more parallelism.
Why it hurts
Keys shift to different partitions. Consumers processing the same customer now see events from two partitions at once, so order breaks. Stateful programs that saved data per key are suddenly looking in the wrong place.
Better approach
Decide whether order for a key matters. If it does, create a new topic with the target count, copy the data over, and cut over with a plan. If it does not, add partitions and warn the client teams.
What people do
They create every topic with hundreds of partitions “just in case.”
Why it hurts
Each partition costs files, memory, and replication work. Broker restarts and controller changes take longer, and most of those partitions sit nearly empty.
Better approach
Size from measured throughput and target consumer counts, add moderate headroom, and revisit the number as the workload grows.
What people do
They start a reassignment of the whole cluster at full speed with no throttle, in the middle of peak traffic.
Why it hurts
Copy traffic competes with clients for disk and network. Latency spikes, consumers lag, and replicas may drop out of the in-sync list, which can even make writes fail.
Better approach
Use a throttle, small batches, off-peak hours, and clear health checks between batches.
What people do
They leave Streams operators unnamed and reorder the steps of the program freely between releases.
Why it hurts
Generated internal topic names shift, so the new version cannot find its old saved state and repartition data. The job may restart from nothing or fail on startup.
Better approach
Name the grouping, repartition, and store operators explicitly, and treat topology changes as planned migrations.
Troubleshooting Playbook
From symptom to likely cause to first check.
| Symptom | Likely cause | First thing to check |
|---|---|---|
| Reassignment stuck at the same percentage | Throttle too low, target broker slow, or leader overloaded | Throttle setting versus the write rate, and target disk health |
| Consumers lag during a move | Copy traffic competes with clients, or cache was flushed | Lower the throttle and check disk read rates on leaders |
| New partitions receive no data | Producers have not refreshed metadata, or keys map elsewhere | Producer metadata age and the key distribution |
| New partitions lose their first messages for a consumer | Reset policy set to start from the latest | Consumer reset setting and when the partitions were created |
| Order broken for some keys after adding partitions | Keys moved to new partitions | Time of the change compared with the ordering errors |
| Request to add partitions is refused | Count is not larger than current, or missing permission | Current partition count and access rules |
| Uneven load after the move | Preferred leaders unbalanced, or hot keys | Leaders per broker and bytes per partition |
| Target broker disk fills up | Too many moves aimed at one broker | Spread targets, reduce parallel moves, free disk space |
| Streams join fails on start | Input topics have different partition counts | Partition counts of both topics |
| Streams job re-reads everything after a release | Internal topic names changed | Whether operators were named and if the step order changed |
| Throttle still active weeks later | Verify step never run | Broker throttle settings and throttled-replica lists on topics |
When something looks wrong, first ask what changed in the last hour. Repartitioning work leaves clear marks in the controller log and in the administrative history, and the timing usually points to the cause.
Real-World and Industry Examples
The same ideas appear in many well-known setups.
Large social and professional networks
LinkedIn, where Kafka was created, built Cruise Control to rebalance clusters with thousands of brokers. Manual planning at that size is impossible, so the balancer watches load and moves partitions continuously.
Cloud-managed Kafka services
Managed offerings from large cloud vendors and Kafka companies hide reassignment behind buttons like “add brokers” or “rebalance.” Under the hood, they run the same add, catch up, and remove steps with throttling.
Kubernetes operators
Tools such as Strimzi run Kafka on Kubernetes, and integrate Cruise Control so that scaling the number of brokers up or down triggers a rebalance plan that moves partitions gently.
Retail and e-commerce peak seasons
Shops that expect sales events add brokers and partitions weeks earlier, rehearse the moves, and freeze changes near the event, since moving data during the peak is the wrong time.
Streaming analytics and fraud detection
Programs that count events per card or per account routinely re-key streams from transaction number to account. Repartition topics are the standard tool and a familiar item in capacity planning.
Data-platform migrations
Teams that inherited a topic with too few partitions commonly copy it into a new topic with a better count using replication tools, then move readers and writers over in stages.
A Day in the Life: ShopStream Orders
Everything you learned, told as one small story.
ShopStream is an online store. Its “orders” topic began life with 6 partitions, keyed by customer number, and 3 brokers. Three years later, orders grew ten times, and the team faces three problems in one quarter.
Problem: readers cannot keep up
The fulfillment program has 6 instances, one per partition, and each is at full speed. Adding more instances does nothing, because extra ones would sit idle. The team needs more partitions.
Decision: new topic or in place?
Fulfillment relies on the order of events for each customer. So the team chooses to create “orders-v2” with 24 partitions, copy the history, and cut over in a quiet window using the drain-and-switch plan.
The cutover
Writers stop, the copier finishes, and fulfillment starts on the new topic from its beginning with idempotent processing. Access rules for the new topic were prepared the day before.
Problem: two new brokers, all the load on the old ones
Two brokers join the cluster, but they are empty. The team generates a plan, saves the current layout, sets a throttle, and moves the busiest partitions in three batches over two nights.
Watching the move
Dashboards show under-replicated partitions rising and falling as copies catch up. When latency creeps up on the second night, the team halves the throttle and continues.
Finishing
They run the verify step, remove the throttle, and ask for preferred leader election so leaders spread onto the new brokers.
Problem: counting orders per product
The analytics team wants counts per product, but the stream is keyed by customer. Their Streams program re-keys by product, and Kafka Streams silently adds an internal repartition topic. The team names the step so the topic name stays stable.
The result
Fulfillment scales to 24 instances, the cluster is balanced across five brokers, and analytics counts are correct. Three different repartitioning jobs solved three different problems.
The team never used a single tool for everything. They picked the right kind of repartitioning for each problem, and that choice was the real skill.
Glossary: Every Term in One Place
A quick reference for the words used in this guide.
| Term | Simple meaning |
|---|---|
| Topic | A named channel of messages |
| Partition | One ordered slice of a topic, stored as files on disk |
| Offset | The position number of a message inside a partition |
| Segment | One of the file chunks that make up a partition’s log |
| Broker | A Kafka server that stores partitions and serves clients |
| Key | A label on a message used to choose its partition |
| Hash | A rule that turns a key into a number |
| Replica | A copy of a partition on some broker |
| Leader | The replica that handles reads and writes for a partition |
| Follower | A replica that copies the leader |
| In-sync replicas | The set of copies that are fully caught up with the leader |
| Preferred leader | The first broker in a partition’s replica list, meant to lead when things are healthy |
| Controller | The broker role that manages cluster metadata and leadership |
| Metadata log | The replicated record of cluster decisions |
| Consumer group | A set of readers that share a topic’s partitions |
| Rebalance | Reassigning partitions among the members of a consumer group |
| Consumer lag | How far a reader is behind the newest message |
| Reassignment | Moving replicas of partitions between brokers or disks |
| Throttle | A speed limit for replication traffic used by a move |
| Co-partitioning | Having matching partition counts and key rules across topics that are joined |
| Repartition topic | An internal topic Kafka Streams uses to regroup records under a new key |
| Changelog topic | An internal topic that backs up the state of a Streams program |
| Cruise Control | A tool that watches load and proposes or runs rebalancing moves |
| Compacted topic | A topic that keeps only the newest record for each key |
| ACL | An access rule that says who may perform which action on which resource |
Frequently Asked Questions
Quick answers to the questions beginners ask most often.
Summary and Key Takeaways
The whole story in a few short lines.
Key Takeaways
- Three jobs, one word: repartitioning can mean adding partitions, moving replicas between brokers, or regrouping records inside Kafka Streams. Each has different tools and different risks.
- Keys decide the partition: because the key’s hash is divided by the partition count, changing the count moves keys, which is why adding partitions can break per-key order.
- Up only, and old data stays: partitions can be added but never removed, and existing messages are never moved. Use a new topic to shrink or to preserve order.
- Move safely by adding first: reassignment adds a new copy, waits for it to be in sync, and only then removes the old one, and its plan is saved in the metadata log so it survives failures.
- Throttle and batch: limit replication speed, move in small groups, watch client latency and lag, and always clear the throttle afterwards.
- Balance leaders too: after a move, check preferred leaders so busy work is shared, and consider automation such as Cruise Control for large clusters.
- Streams regroups automatically: key-changing operations create internal repartition topics, joins need co-partitioned inputs, and named operators keep the topology stable across releases.