How would you design a Kafka topic and consumer group layout for 50 microservices consuming the same event stream, and what breaks if you get partition count wrong?
Quick Answer
Give every consuming service its own consumer group so each gets a full independent copy of the stream, size partitions to the maximum parallelism any single group will ever need, and set replication factor 3 with min.insync.replicas=2 for durability. Getting partition count wrong is expensive because Kafka does not let you safely lower it and raising it later breaks per-key ordering for existing data.
Detailed Answer
Picture a company newsletter mailed to 50 different departments. Every department needs its own full copy delivered to its own mailbox (a consumer group), rather than 50 departments fighting over shared mail slots. But within a single department that splits reading across several clerks (consumer instances in one group) to keep up with volume, you only need as many mail slots (partitions) as clerks working that day.
In Kafka, a consumer group is the unit of independent consumption: every group gets its own copy of every message in the topic, tracked by its own offsets in __consumer_offsets. That is why 50 microservices reading the same event stream should be modeled as 50 separate consumer groups, not 50 consumers crammed into one group — cramming them into one group would split the stream 50 ways instead of replicating it 50 times, meaning most services would silently see only a fraction of the events. Kafka was designed this way so that adding a new downstream consumer of an existing stream requires zero changes to the topic or to other consumers — it's an additive, decoupled architecture, which is the entire value proposition over a traditional message queue with single-consumer semantics.
Internally, partition count sets a hard ceiling on parallelism per group: a group can have at most as many active consumers as there are partitions, because each partition can only be owned by one consumer within a group at a time. For 50 independent services with wildly different processing speeds, you pick the partition count based on the neediest consumer group's expected peak parallelism — commonly 24 to 48 partitions for a mid-size event stream — and set replication-factor=3 so the topic survives a broker or AZ failure. A schema registry (a separate service that stores and versions the Avro/Protobuf message schema) sits alongside the topic so all 50 services can evolve their event contract independently without a synchronized deploy.
At scale, the operational risks multiply with consumer count: 50 consumer groups on one topic means 50 independent lag curves to monitor, and a single slow consumer group doesn't block the others but can mask a real problem because dashboards aggregate lag by topic instead of by group. Retention (how long Kafka keeps messages before deleting them) has to be sized for the slowest consumer group plus a safety margin — if any one of the 50 services falls behind by more than the retention window, it silently loses data rather than erroring loudly. Engineers watch min.insync.replicas violations, under-replicated partition counts, and per-group max lag as the top three signals.
The gotcha almost everyone misses: you can increase partition count later, but doing so reassigns the hash-to-partition mapping for every key, so all 50 consuming services that relied on same-key-same-partition ordering will see a discontinuity in ordering exactly at the moment you repartition — old messages for a key sit in the old partition, new messages for the same key land in a different one. Because of this, teams almost always over-provision partition count up front rather than trying to right-size it later, even though excess partitions cost more open file handles and replication overhead on every broker.