Message Brokers: RabbitMQ & Kafka
Message Brokers: RabbitMQ & Kafka
When services need to communicate without tight coupling, a message broker sits between them: producers send messages to the broker, and consumers read from it at their own pace. NestJS ships two first-class transporters for the most widely used brokers — RabbitMQ (AMQP queues) and Apache Kafka (distributed log topics). Choosing the right one shapes your system's delivery guarantees, throughput, and operational complexity.
RabbitMQ — queue-based messaging
RabbitMQ implements the AMQP protocol. Producers publish messages to exchanges; the exchange routes them to one or more queues; consumers pull from a queue and send an acknowledgement (ack) once processing succeeds. Unacknowledged messages are redelivered.
Register the RabbitMQ transporter in main.ts:
A consumer handler uses @MessagePattern (RPC) or @EventPattern (fire-and-forget):
noAck: false, a message stays in the queue until your handler explicitly acks it. If the process crashes mid-flight, RabbitMQ redelivers to another consumer — ensuring at-least-once delivery.
Apache Kafka — topic-based log streaming
Kafka stores messages in ordered, immutable topic partitions (a distributed commit log). Consumers belong to a consumer group; each partition is assigned to exactly one member of a group, enabling horizontal scaling while guaranteeing order within a partition. Messages are retained for a configurable period — not deleted on consumption.
Subscribing to a Kafka topic uses the same @EventPattern decorator:
Consumer groups and scaling
In Kafka, all service replicas share the same groupId. Kafka assigns each partition to one replica — so adding replicas increases throughput up to the number of partitions. In RabbitMQ, multiple consumers on the same queue compete for messages in round-robin fashion — scaling is simpler but there are no ordered partitions.
Choosing between them
- RabbitMQ: lower operational overhead, rich routing (direct, topic, fanout exchanges), mature dead-letter support, ideal for work queues and RPC patterns.
- Kafka: extremely high throughput (millions msg/s), durable ordered log, message replay, multiple independent consumer groups reading the same stream.
- Both: support manual acknowledgements and at-least-once delivery; both have NestJS first-class support with identical decorator API.
Summary
NestJS supports both RabbitMQ (AMQP, queue-based, ack-driven) and Kafka (topic partitions, consumer groups, durable log) through identical @EventPattern / @MessagePattern decorators. RabbitMQ excels at task queues and routing; Kafka shines at high-throughput event streaming and replay. Always use manual acknowledgements in RabbitMQ to guarantee at-least-once delivery, and group your Kafka consumers correctly to balance partitions across replicas.