Medium java spring

When would you choose Kafka over RabbitMQ

The 30 second answer

I choose Kafka when I need a durable, replayable log, high-throughput event streams, and several independent consumer groups reading the same data at their own pace. I choose RabbitMQ when I need flexible routing with exchanges, competing consumers on a work queue, or per-message acknowledgement and retry. RabbitMQ also offers streams if I want a log-like structure there, but queues remain its core model. The two solve different shapes of problem, not the same problem at different speeds.

I do not start from throughput slogans. I start from the consumption model.

Kafka is a durable, partitioned, append-only log. Producers append; consumers pull from an offset they control. The Kafka design docs contrast this with a traditional queue: records are not deleted when they are read, they are retained for a configured period, and many independent consumer groups can read the same topic at their own pace, including rewinding and replaying. Order is per partition. Scaling a group means adding partitions. This is the right shape for event streams, audit and change data, search or cache indexing, and fan-out to several downstream systems that must not interfere with each other.

RabbitMQ's core model is the queue. The RabbitMQ 4.4 queues guide describes a queue as an ordered collection of messages, enqueued at the tail and dequeued at the head, FIFO except where features such as priorities or requeueing change what the consumer observes. Once a message is acknowledged, it is removed. Several consumers on the same queue are competing consumers: each message goes to one of them. Routing is flexible: publishers send to an exchange, and bindings decide which queues receive a copy. Consumer acknowledgements and publisher confirms, documented in the confirms guide, give per-message data-safety hooks. This is the right shape for a work queue, a request that must be processed by exactly one worker, and topologies that need topic, direct or fanout routing rather than a single partitioned key.

RabbitMQ streams exist as a complement, not a replacement. The streams guide describes an append-only log with non-destructive consumption, and it says streams "were not introduced to replace queues but to complement them," for large fan-out and replay. If the requirement is specifically "a log on RabbitMQ," streams can be a fit. If the requirement is a large, independently replayable event backbone with many consumer groups, I still pick Kafka.

A practical rule I will say in an interview: if the consumer needs to say "give me this command once, and delete it when I ack," I look at RabbitMQ (or another queue). If the consumer needs to say "I am an independent reader of this history, I can catch up from an offset, and other readers should not take my messages," I look at Kafka. At-least-once plus idempotency still applies on both sides; neither broker makes a payment API exactly-once by itself.

Sources (5)
  1. Kafka 4.4 design (log versus traditional messaging, pull consumers, retention)kafka.apache.org
  2. Kafka 4.4 introductionkafka.apache.org
  3. RabbitMQ 4.4: Queuesrabbitmq.com
  4. RabbitMQ 4.4: Streams and super streamsrabbitmq.com
  5. RabbitMQ 4.4: Consumer acknowledgements and publisher confirmsrabbitmq.com