'Which message broker' is one of the most consequential platform decisions a team makes. Migrations are painful; the wrong choice costs years. The good news: the decision tree is actually short once you separate use case from preference.
Step 1: define your traffic shape
Throughput: thousands or millions of messages/sec? Latency: best-effort batch or sub-100ms? Retention: minutes or months? Ordering: per-key or global? Until you answer these, comparison is theater. Most teams skip this step and pick by what they used last.
Kafka — the default for event streaming
Best for: high throughput (100K+/sec sustained), durable replay (days to weeks), exactly-once semantics in-cluster, ecosystem (Streams, Connect, Schema Registry). Worst for: low-latency RPC (no), small teams (operationally heavy), variable-payload sizes (chunking awkward).
Pulsar — Kafka semantics + multi-tenancy
Geo-replication built in. Tiered storage (hot in BookKeeper, cold in S3) makes long retention cheap. Multi-tenant isolation cleaner than Kafka's. Operational complexity higher; you run Pulsar AND ZooKeeper AND BookKeeper.
RabbitMQ — work queues and routing
Best for: task queues with retry/DLQ, complex routing (topic/fanout/headers), small-to-mid throughput. Worst for: replay (delivered-and-gone), durable history, exactly-once across consumers.
NATS / JetStream — lightweight and fast
Best for: low-latency pub/sub (<1ms), IoT, microservice eventing without ops overhead. JetStream adds persistence. Worst for: huge throughput, deep ecosystems, complex routing.