Skip to content

relaybus vs alternatives ​

relaybus is an event bus built on the transactional outbox. The tools below solve neighbouring problems and are often the right choice. This page states what each one documents; verify details in their documentation before deciding.

What it isSurvives a restartWritten in your database transactionChoose it when
relaybusEvent bus built on the transactional outbox: PostgreSQL and MongoDB stores, Kafka and RabbitMQ transports, per-handler deliveriesYes, events live in your databaseYesEvents must never be lost or phantom, and handlers need retries, dead letters and ordering keys
@nestjs/event-emitterIn-process event emitter built on eventemitter2No persistence is documentedNoSimple in-process notifications where losing an event on restart is acceptable
@nestjs/cqrsCommandBus, QueryBus, EventBus and sagas; the docs say sagas and event handlers run in memoryNo built-in persistenceNoYou want CQRS structure; it can sit on top of an outbox
@nestjs/outboxTransactional outbox module from the NestJS organisation: PostgreSQL, MySQL and in-memory stores, relay with leases and retries, dead-letter table, inboxYes with the database storesYesYou need MySQL, or a NestJS-organisation module; compare features with relaybus before choosing
BullMQJob queue on Redis with retries, delayed jobs and flows; at-least-once in the worst caseYes, in RedisNo, jobs are stored in Redis and cannot join a SQL or MongoDB transactionYour stack is Redis-based and background jobs matter more than event atomicity
pg-bossJob queue on PostgreSQL using SKIP LOCKED, with retries, dead letter queues, scheduling and pub/sub; jobs can be created in your own transactionYes, in PostgreSQLYes, through its database adaptersYou want a PostgreSQL job queue with scheduling; relaybus is an event bus with per-handler deliveries and transports
Kafka client directlyA distributed log; the idempotent producer and transactions give exactly-once within KafkaYes, in KafkaNo, producing to Kafka is a second writeYou consume and produce only inside Kafka; add an outbox when a database write must be announced

This table summarises the vendors' own documentation as of October 2026; check their docs for current details. Full comparison and sources: https://berkcansavur.github.io/relaybus/comparison.

Notes on each alternative ​

@nestjs/event-emitter. Built on eventemitter2. Its documentation describes an observer implementation and mentions no persistence or delivery guarantee. Errors thrown by a listener are logged by default (suppressErrors). It is the simplest option when events are in-process notifications.

@nestjs/cqrs. Provides CommandBus, QueryBus, EventBus and sagas. Its documentation states that sagas and event handlers run in memory. It does not describe an outbox. Nothing prevents you from using it with relaybus as the durable transport underneath.

@nestjs/outbox. A transactional outbox module published under the NestJS organisation. Its repository describes PostgreSQL and MySQL stores, a relay with leases, retries and a dead-letter table, and an inbox that deduplicates redeliveries. If you need MySQL, evaluate it. relaybus additionally provides a MongoDB store, Kafka and RabbitMQ transports with publisher confirms and offset-after-inbox semantics, ordering keys and a contract-tested store interface.

BullMQ. A queue library on Redis with retries, delayed jobs and flows. Its documentation says it aims for exactly-once delivery and delivers at least once in the worst case. Because jobs live in Redis, adding a job cannot be part of your SQL or MongoDB transaction. It is a good fit when you already run Redis and need background job features.

pg-boss. A PostgreSQL job queue using SKIP LOCKED, with retries, dead letter queues, scheduling and pub/sub. Its documentation says jobs can be created inside an existing transaction through adapters for Drizzle, Knex, Kysely and Prisma. It models jobs for queues; relaybus models events with one delivery per subscribed handler, per-key ordering and broker routes. For cron-style schedules, prefer a job queue.

Kafka directly. Kafka's idempotent producer and transactions give exactly-once semantics within Kafka. Its own design documentation notes that exactly-once with an external system needs cooperation from that system. Producing to Kafka and writing your database are two writes; an outbox makes them one.

Choosing quickly ​

If you needConsider
In-process notifications, loss on restart acceptable@nestjs/event-emitter
CQRS structure (commands, queries, sagas)@nestjs/cqrs, optionally with relaybus for durable events
Atomic publish with PostgreSQL or MongoDB, per-handler retries, ordering keys, Kafka or RabbitMQrelaybus
Transactional outbox on MySQL@nestjs/outbox
Background jobs and rate limiting on RedisBullMQ
A PostgreSQL job queue with schedulingpg-boss
Streaming processing entirely inside KafkaKafka clients and Kafka transactions

Sources ​

Comparison checked on 18 October 2026.

Released under the MIT License.