Skip to content

What is Kafka rebalancing?

Kafka
Chad Harris·August 29, 2026·6 min read

Kafka rebalancing is the process where a consumer group’s partitions are redistributed across its members after a membership or subscription change. Under the default eager protocol every consumer in the group stops fetching until new assignments are issued, so consumer lag grows while the rebalance runs. The group coordinator, a broker elected for each consumer group, detects the change and drives the reassignment.

Rebalancing itself is not the problem. It is Kafka doing exactly what it was designed to do. The pain arrives when a group’s membership grows past what anyone is watching. Every extra member means more work for the coordinator, and frequent or slow rebalances show up as lag on the topic long before anyone thinks to look at membership. Most of the worst rebalancing incidents I have worked on were membership problems wearing a performance costume.

Root cause analysis and troubleshooting

A rebalance is triggered by a defined set of conditions. A consumer joins or leaves the group, a consumer is considered dead by the coordinator, or the topic metadata changes, for example when partitions are added. How groups assign work is covered in Kafka consumer groups. Unexpected rebalances almost always trace back to one of three timeouts.

Trigger join · leave · timeout Coordinator revokes assignments Members rejoin New assignments issued max.poll.interval.ms  300000 session.timeout.ms  45000 heartbeat.interval.ms  3000 Eager all members paused for the whole window Cooperative only moved partitions pause The group coordinator is a role on one of the brokers — not a separate service
Screenshot to come

A consumer group caught mid-rebalance, with the lag spike either side of it.

The consumer must call poll() again before the processing deadline expires: max.poll.interval.ms, default 300000 (5 minutes). A batch that takes longer than this to process makes the consumer leave the group.

The broker must receive a heartbeat before the session expires: session.timeout.ms, default 45000 (45 seconds). A JVM garbage-collection pause or network partition longer than this gets the consumer evicted and triggers a rebalance.

The heartbeat cadence itself: heartbeat.interval.ms, default 3000 (3 seconds). Defaults are from the Apache Kafka consumer configuration reference.

Broker-side changes are a separate case. Adding brokers to a cluster does not rebalance existing partitions. Only new partitions land on new brokers unless partitions are explicitly reassigned.

The diagnosis step is where teams lose the most time, because the obvious metrics point the wrong way. In a talk on Kafka operational issues I walked through an incident where a service scaled to 800 instances with 100 consumers per instance, and the group ended up with 79,000 idle members against about a thousand active assignments. Rebalances took longer, lag built, and one broker sat at 100% CPU while every other broker was fine. The team read that as a capacity problem, so the next decision, which I described at the time as more gasoline onto the fire, was to scale Kafka and add brokers. Adding brokers made rebalance activity worse, not better. The root cause was never capacity. Nobody had metrics on consumer group membership size or coordinator request rates, so the one number that explained everything was invisible. The incident was finally cracked open by a vendor support ticket that came back with too many inactive members in the group.

The lesson I took from it: when rebalances slow down and lag climbs, check group membership and coordinator load before you buy hardware.

Mitigation strategies and architecture patterns

Three mechanisms reduce or remove the stop-the-world pause.

Incremental cooperative rebalancing lets consumers keep the partitions they already own while only the moved partitions change hands. It shipped as the CooperativeStickyAssignor in Kafka 2.4 (KIP-429). The default partition.assignment.strategy still lists RangeAssignor first, so a consumer group runs the eager protocol unless the assignor is configured explicitly.

Static membership gives each consumer a persistent identity: group.instance.id (KIP-345). A static member that restarts and rejoins within session.timeout.ms receives its previous assignment without triggering a rebalance, which is what makes rolling pod restarts in Kubernetes survivable.

The next-generation consumer rebalance protocol moves assignment logic to the group coordinator and removes the global synchronization barrier entirely, so a consumer whose assignment does not change is not interrupted at all. It is generally available in Apache Kafka 4.0 (KIP-848).

Mitigation is also about the changes you make around rebalancing, and two of them have scarred me. The first is partition increases. They are not zero cost for consumers, and you need to know where your consumers will start reading before you scale. I watched a team increase partition counts to scale a service, and because producers discovered the new partitions before consumers finished rebalancing, messages landed on partitions the consumers did not know existed. The consumers were on the default auto.offset.reset of latest, so when they finally picked up the new partitions they started reading from the end. Hundreds of messages per partition, across something like 100 partitions, were silently skipped. No errors, no alerts, workflows stuck, SLAs broken. Partition planning has its own page in Kafka topic partition best practices, and the short version is that partition changes are consumer events, not just broker events.

The second is timeout tuning that trades safety for convenience. One team raised max.poll.interval.ms to 20 minutes so they could pre-batch thousands of messages into one. It ran fine for 12 months, until a poison batch blew past the window and put the group into a loop of consumer failure and rebalance. Treat max.poll.interval.ms as a failure detection timeout, not a processing budget. And whatever you change, make one change at a time and treat broker and consumer config like code, version controlled and applied by CI.

Monitoring and impact assessment

Rebalance activity is exposed through the consumer’s coordinator metrics: rebalance-latency-avg, rebalance-rate-per-hour, failed-rebalance-rate-per-hour and last-rebalance-seconds-ago, documented in the Apache Kafka monitoring reference.

Consumer group lag is the impact signal. Lag is not exposed through JMX directly. It requires an exporter that polls the AdminClient API and calculates the delta between log end offsets and committed consumer offsets, tracked per group and per partition, the approaches compared in how to monitor Kafka consumer lag. A rebalance event that correlates with a lag spike on the same group is the standard way to attribute an SLO breach to rebalancing rather than to slow processing. Rebalance pauses are also a recurring theme in Kafka vs RabbitMQ performance, where they are part of the log model’s operational price. The wider monitoring stack sits in the complete Kafka guide.

The standard dashboard set will tell you something is wrong and stop there. Consumer lag, broker CPU and memory, network throughput, under-replicated partitions: they are all useful, and none of them told us why in the incident above. What was missing was membership. Track consumer group membership size and coordinator request rates alongside lag, because a group quietly accumulating idle members looks completely healthy on every default chart until the rebalances start dragging. That gap between something is wrong and here is why is exactly where rebalancing incidents live.

FAQ

What is the purpose of rebalancing in Kafka?

Rebalancing redistributes a consumer group’s partitions across its members when membership or subscriptions change, so every partition keeps exactly one assigned consumer. It is the mechanism that lets a group scale out, survive consumer failures and pick up newly added partitions.

How do you avoid Kafka rebalances?

Unnecessary rebalances are avoided by tuning the three timeouts so healthy consumers are not evicted, configuring the CooperativeStickyAssignor so only moved partitions change hands, and setting group.instance.id so restarting consumers rejoin without triggering a rebalance. On Kafka 4.0, the KIP-848 protocol removes the global synchronization barrier entirely.

Related reading