How do you choose an event broker for commerce: Redis, RabbitMQ, SQS or Kafka?
Short answer: event-driven commerce makes sense when checkout cannot wait for ERP, PDF, email, WMS, CRM or search indexing. Choose Redis Streams for simple fast streams and live status, RabbitMQ for complex routing and self-managed infrastructure, AWS SQS for a simple managed queue on AWS, FIFO for order/customer-level ordering, and Kafka when the event log and replay are a data product, not just a queue.
First definition: event-driven does not mean "put everything in a queue"
Event-driven commerce means the system reacts to business facts: order accepted, payment captured, stock reserved, invoice requested, shipment created, return received. An event describes something that already happened; it is not a command saying "make me a PDF now". That distinction matters because it creates resilient flows, not just delayed slow operations.
In classic checkout, a monolith often does everything synchronously: saves the order, calls ERP, generates an invoice, sends email, updates CRM, reserves stock and refreshes the search index. One slow system can freeze the cart. Event-driven design separates the critical path from side effects. The shopper should get a checkout decision quickly, while the rest of the system catches up through queues and workers.
This is not free magic. Asynchrony introduces retries, duplicates, out-of-order delivery, DLQs, monitoring, idempotency and manual operations. A good project does not ask "which broker is best?". It asks "which guarantees does this specific flow need?".
Decision map: Redis, RabbitMQ, SQS or Kafka
Redis Streams is a good choice when you need a very fast simple stream, live statuses, a small number of consumers and Redis is already in the stack. RabbitMQ makes sense when routing matters more than simplicity: exchanges, bindings, routing keys, dead-letter exchanges, different queues for different consumers. AWS SQS is a strong default on AWS when you want a managed queue without operating a broker.
SQS Standard gives high scale and at-least-once delivery, but the application must handle duplicates and occasional out-of-order delivery. SQS FIFO is for flows where operation order is critical, for example per order or per customer, but it has different limits and needs message group design. Kafka makes sense when you need a durable event log, replay, many independent consumers, analytics and data integration.
In commerce, you often do not choose one tool for everything. Checkout side effects may use SQS, live order tracking Redis Streams, B2B routing RabbitMQ, and analytics/data-platform events Kafka. What matters is a consistent domain event contract and clarity on which events are financially critical.
- Redis Streams: fast statuses and simpler streams close to the application.
- RabbitMQ: rich routing, exchange/binding and controlled infrastructure.
- AWS SQS: managed queue on AWS, operational simplicity, at-least-once.
- SQS FIFO: ordering per message group and deduplication for critical sequences.
- Kafka: durable event log, replay, data platform and many independent consumers.
Checkout: what should remain synchronous
The worst event-driven design sends everything asynchronously and pretends consistency disappeared. Checkout must clearly separate critical decisions from side effects. Payment authorization, price validation, stock reservation or trade-credit checks may be part of the business decision. PDF invoice, email, CRM update, search indexing and many reporting integrations usually should not block the shopper.
A good model starts with the command side: accept the cart, check conditions, store order intent, confirm payment or pending status, and only then emit events. If ERP is the system of truth for stock or trade credit, decide whether checkout waits for ERP, uses a local read model or accepts the order conditionally with later validation.
At GMI we often design this as a narrow production slice: NestJS order service, PostgreSQL for transactional state, broker for side effects, workers for PDF/ERP/CRM/WMS and an operational dashboard for errors. This is Black Friday architecture, not just "a queue in code".
Delivery guarantees: at-least-once means duplicates
AWS documents that SQS Standard provides at-least-once delivery, but a message may be delivered more than once and occasionally out of order. That is not a flaw to hide. It is a contract the application must accept. Invoice consumers, ERP sync and email workers must be idempotent.
Idempotency means the same event processed twice does not create two invoices, two payments, two shipments or two emails with conflicting status. In practice, you store event id, order id, version, idempotency key and processing status. The operation can be repeated without changing the business result.
If ordering is critical, choose a per-aggregate model: order events for one order, customer events for one customer, inventory events for one SKU/location. SQS FIFO uses message groups, and Kafka preserves order within a partition for the same key. Global ordering for the whole store is usually unnecessary and expensive.
Retries, DLQs and poison messages
Every event-driven system must answer one question: what happens when a worker cannot process a message? Unlimited retry can clog the queue. No retry loses temporary ERP failures. Too low a limit moves normal delays to the dead-letter queue. Too high a limit hides a defect for hours.
SQS DLQ lets you isolate messages that could not be processed, analyze the cause and redrive them. AWS recommends setting `maxReceiveCount` high enough so the system can survive transient errors. RabbitMQ has dead-letter exchanges and acknowledgements: the broker removes a message only after the consumer confirms processing with an ack.
Operationally, a DLQ is not a trash bin. It is a task list for the system and the team. It needs an alert, owner, runbook, message-age metrics and a decision: replay, manual fix, cancel, refund, contact customer. Without that, event-driven design only moves failures from checkout to backoffice.
Event contract: schema, versioning and ownership
In commerce, an event is a contract between teams. `order.accepted.v1` needs an owner, schema, version, required fields, time semantics and compatibility rules. If an ERP worker assumes `customerVatId` always exists and checkout stops sending it, the failure appears far away from the change.
Not every event should contain full data. Sometimes an id is enough and the worker fetches a snapshot from an API. Sometimes you need an immutable payload because price, tax and shipping address must reflect the purchase moment. That is a domain decision, not a technical preference.
Good events are not named after implementation. `sendEmail` is a command to a specific worker. `orderPaid`, `invoiceRequested`, `shipmentCreated`, `returnReceived` are business facts. That is what separates event-driven architecture from distributed spaghetti.
Monitoring: lag, message age and business impact
It is not enough to know that a queue exists. In commerce you need to know how many orders wait for ERP, how many invoices are in DLQ, the age of the oldest message, what percentage of retries succeed, how many events a worker processes per minute and whether backlog grows faster than consumption.
The most important metrics are business metrics: payment captured but order not exported, order accepted but invoice missing, shipment created but customer not notified, return received but refund not started. Broker metrics help, but alone they do not tell the CFO how much money is stuck in integration.
At GMI we design the operational dashboard together with queues. Support and operations must see order status, last event, retry count, error reason and safe actions: replay, skip, manual fix, contact customer. That turns event-driven from technology into an operating process.
Implementation cost: what actually moves the budget
Extracting a safe event-driven path for checkout, ERP/PIM/WMS, invoices and email usually starts around PLN 160,000-300,000, depending on integration count and current monolith quality. The broker itself is cheap. The expensive parts are domain model, idempotency, observability, retries, DLQs, tests and the operating model for fixing failures.
The smallest useful scope is: flow map, event contract, broker, a few workers, DLQ, monitoring, idempotency store and checkout regression scenarios. Larger scopes include order service, outbox pattern, saga/workflow, ERP sync, WMS, marketplace, multi-country, Kafka/data platform and historical event migration.
GMI provides an initial estimate within 48 hours, but fixed price after DDT. In DDT we decide which operations can be async, which must remain synchronous, what needs per-aggregate ordering, who owns the DLQ and which metrics prove the store is peak-ready.
Pre-development checklist
This checklist helps verify whether event-driven design solves a real constraint or only adds complexity.
- Which checkout steps must be synchronous, and which can be async?
- Is every consumer idempotent with event id / order id / version?
- Do we need global ordering, or only per order/customer/SKU?
- What goes to the DLQ, and who owns the error runbook?
- Can the worker safely replay an event after an ERP outage?
- How do we monitor backlog, message age, retries and business impact?
- Does the event contract have an owner, version and compatibility rules?
How GMI designs event-driven commerce
We start with DDT and a process map: checkout, payment, stock reservation, ERP, PIM, WMS, invoice, email, CRM, search, mobile push and reporting. Then we separate the critical path from side effects and choose transport based on required guarantees, not fashion.
Technically, we often combine NestJS, PostgreSQL, Redis, RabbitMQ, AWS SQS, sometimes Kafka, Next.js, React Native and MedusaJS. In commerce, the queue is only part of the model: transactional outbox, idempotency, retry, DLQ, audit log, operational dashboard and checkout regression tests matter just as much.
Commercially, the client gets source-code ownership, no vendor lock-in, fixed price after DDT and post-launch maintenance. This matters because event-driven commerce lives long after launch: new sales channels, ERP integrations, marketplace flows and mobile apps keep adding new events.
Sources and further reading
Amazon SQS Standard queues: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/standard-queues.html
Amazon SQS FIFO queues: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-fifo-queues.html
Amazon SQS dead-letter queues: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html
RabbitMQ AMQP concepts: https://www.rabbitmq.com/tutorials/amqp-concepts
Redis Streams documentation: https://redis.io/docs/latest/develop/data-types/streams/
Apache Kafka introduction: https://kafka.apache.org/intro/
GMI NestJS order microservices guide: /blog/nestjs-order-microservices-when-to-split
GMI MACH B2B ERP/PIM integrations guide: /blog/mach-b2b-ecommerce-integrations-erp-pim
GMI observability for commerce peaks guide: /blog/observability-commerce-peaks-black-friday
Frequently asked questions
- When should ecommerce move to event-driven architecture?
- When checkout or order management waits for slow side effects: ERP, PDF invoices, email, WMS, CRM, search indexing, webhooks or reporting. Event-driven design makes sense when order acceptance must be separated from work that can happen without blocking the shopper.
- Redis, RabbitMQ, AWS SQS or Kafka: what should we choose?
- Choose Redis Streams for simple fast streams and live statuses. RabbitMQ for complex routing and self-managed infrastructure. AWS SQS for managed queues on AWS and operational simplicity. SQS FIFO for ordering per order/customer. Kafka when you need a durable event log, replay and data platform.
- Does event-driven guarantee exactly-once order processing?
- Do not assume that. In practice, design consumers as idempotent because messages can return after retries or worker failure. Even when a broker offers deduplication in a specific scope, domain logic must protect against duplicate invoices, payments or shipments.
- What is a DLQ and why does it matter in commerce?
- A DLQ, or dead-letter queue, stores messages a worker could not process after a configured number of attempts. In commerce, a DLQ needs an alert, owner and runbook because it can mean orders without invoices, no ERP export, delayed shipments or customers without notifications.
- How much does event-driven commerce implementation cost?
- A safe first scope for checkout, ERP/PIM/WMS, invoices and email often starts around PLN 160,000-300,000. Cost depends on integration count, monolith quality, observability, retries/DLQ, idempotency and whether you need an order service, outbox or Kafka/data platform.
- Does AWS SQS create vendor lock-in?
- It can increase operational dependency on AWS, but domain logic should not depend on SQS itself. At GMI we design transport through adapters, event contracts and tests so the system can move to RabbitMQ, Kafka or another broker without rewriting checkout.
Content updated: July 11, 2026