"Should we use Kafka or RabbitMQ" is one of the most asked and most badly answered questions in backend engineering. Most answers turn into a benchmark fight about throughput. Throughput is real, but it is not the decision. The decision is what the two tools fundamentally are, and once you see that, the choice usually makes itself.
Here is the one-sentence version I give juniors: RabbitMQ is a queue that delivers a message and forgets it, Kafka is a log that stores messages and lets you replay them. Everything else follows from that.
RabbitMQ is a message broker built around the queue and the ack. A producer publishes, the broker routes the message to a queue through an exchange, a consumer pulls it, processes it, and acknowledges it. Once acknowledged, the message is gone. This model is perfect for work. Think of a message as a task that exactly one worker should perform once: resize this image, send this email, charge this card. RabbitMQ gives you rich routing (direct, topic, fanout exchanges), per-message priority, and per-message time to live. If your mental model is "I have jobs and I need workers to do them," RabbitMQ fits like a glove.
Kafka is a distributed, append-only commit log. Producers append messages to a partition, and messages are not removed when read. Instead, each consumer group tracks its own offset, its own bookmark, into the log. Messages stick around for a configured retention period, whether that is days or forever. This is a completely different model. A message in Kafka is not a task to be consumed once, it is a fact that happened, and any number of independent consumers can read it now or replay it later. That is why Kafka owns event streaming, change data capture, metrics and log pipelines, and any case where you need multiple systems reacting to the same stream of events, or you need to reprocess history with new code.
The replay point is the one that most cleanly separates them. Imagine you ship a bug in your analytics consumer and it miscounts events for a day. With Kafka, you fix the code, reset the offset, and reprocess yesterday's events, because they are still in the log. With RabbitMQ, those messages were acknowledged and deleted the moment they were first consumed. They are gone. There is nothing to replay. If replay or multiple independent readers matter to you, that alone decides it.
Ordering and scale reinforce the split. Kafka guarantees order within a partition and scales by adding partitions and brokers, which is how it reaches very high sustained throughput. RabbitMQ can scale too, but its strength is flexible routing and per-message control, not raw firehose throughput across a partitioned log.
So here is the decision procedure I actually use:
- Is each message a task that one worker should do once and then discard? RabbitMQ.
- Do you need complex routing, priorities, or per-message TTL on those tasks? RabbitMQ.
- Is each message an event that multiple systems may care about, now or later? Kafka.
- Do you need to replay history, or add a new consumer that reads from the beginning? Kafka.
- Are you moving a very high, ordered volume of events continuously? Kafka.
And the answer a senior engineer is not afraid to give: sometimes both. It is completely normal to run RabbitMQ for command-style task queues and Kafka for the event backbone in the same system. They are not competitors so much as different shapes. Reaching for one everywhere because it is the one you know is the actual mistake, more than picking "wrong" between them.
Decide on the model first, the delivery semantics second, and the benchmark last. If you start from throughput numbers you will end up defending a choice you made for the wrong reason.
I put the full comparison, including the delivery guarantee details and a worked design, here: https://www.systemdesign.academy/interview/design-kafka
Top comments (0)