Module 15 · Lesson 3 of 4
Consumer groups and ordering
Scaling consumers without losing order.
On the night the band's tickets go on sale, Gatepass publishes 8,000 booking events a second. One email worker can send about 500 emails a second, so a single consumer falls further behind every second. You need many copies of the email service reading the same topic, without two of them sending the same email and without a fan getting "your ticket" before "your payment went through".
A consumer group shares the work
In Kafka, consumers that do the same job join a consumer group under one name, such as email-sender. Kafka divides the topic's partitions among the group's members, and the rule is strict: each partition is read by exactly one consumer in the group at a time. A consumer can own several partitions, but a partition never has two owners in one group.
Different groups are completely independent. The email-sender group and the analytics group each get every event, each with their own offsets. Within a group, work is split. Across groups, work is copied. That is pub/sub and a work queue in a single system.
Why one owner per partition? Because that is what keeps order cheap. If two consumers read the same partition, they would race: one might handle offset 8 while the other is still on offset 7. With one owner, the partition is processed strictly in sequence, and the owner tracks progress with a single committed offset.
Partitions cap your parallelism
The one-owner rule has a direct consequence: a group can never have more busy consumers than the topic has partitions. Six partitions and ten consumers means four consumers sit idle, waiting in case someone dies.
So the partition count is a decision about future scale, made on day one. Work it out from the numbers. At peak Gatepass produces 8,000 events a second, and one email consumer handles about 500. That needs at least 16 busy consumers, so the topic needs at least 16 partitions. Teams usually add headroom and pick something like 24 or 32, since adding partitions later moves keys around.
Try it. Press play and add consumers until the lag stops climbing. Then keep going past six and watch the extra consumers do nothing.
Try it
One consumer group, six partitions
Press play. Add consumers until the lag stops growing, go past six, then switch keys off and watch the order of each booking's events.
Each booking's events share a partition, so one consumer handles them in order.
In / out per tick
5 / ~4
Lag
0
Handled
0
Out of order
0
Order is per key, not per topic
In the visual, keep "Key: booking id" on and the out-of-order counter stays at zero. Every event for booking #112 lands in the same partition, and that partition has exactly one owner, so Created, Paid and Ticketed are handled in sequence.
Now switch to "No key". Events are sprayed across partitions, so booking #112's Created might sit at the back of a long partition while its Paid sits at the front of a short one. A different consumer handles Paid first, and the counter starts climbing. For email that might mean sending "here is your ticket" before "payment received". For a seat counter it might mean releasing a seat that was never held.
Kafka gives you order in exactly this shape: within a partition, and therefore within a key. There is no global order across the topic, and you almost never need one. You need each booking's story to make sense, not every booking's story to interleave in a fixed way.
Rebalancing: when the group changes
The assignment of partitions to consumers is recalculated whenever the group changes: a consumer joins, a consumer leaves cleanly, or a consumer stops sending heartbeats because it crashed or froze in a long garbage-collection pause. This is a rebalance.
In the classic protocol a rebalance is stop-the-world. Every consumer gives up its partitions, the group agrees on a new assignment, and only then does consuming resume. You saw it in the visual: changing the consumer count pauses the whole group and the lag jumps. Newer Kafka versions rebalance incrementally, moving only the partitions that need to move while the rest keep working, which shrinks the pause a lot.
Rebalances also cause duplicates. Suppose email-2 sends ten emails, then crashes before it commits its offset. The new owner of its partitions starts from the last committed offset and sends those ten emails again. Kafka didn't lose anything, it just can't know work was done that was never recorded. The next lesson is about living with exactly this.
Check yourself
The email topic has 12 partitions. To handle a spike you scale the email-sender group from 10 to 20 consumers. What happens?
Your turn
The SMS service can send 200 messages a second per instance, and peak is 8,000 bookings a second. How many partitions does the SMS topic need, what key would you use, and what happens to lag during a deploy?
Key takeaways
- A consumer group splits a topic's partitions among its members. Each partition has exactly one owner per group; separate groups each get everything.
- Busy consumers can't exceed partitions. Size the partition count from peak rate divided by per-consumer rate, plus headroom.
- Order is guaranteed per partition, so key by the entity whose events must stay in order.
- Rebalances pause consumption and replay uncommitted work. Expect duplicates and keep processing within the poll timeout.
Finished reading?
Mark it complete to tick it off in the course.