Design & Architecture

Asynchronous Messaging & Eventing

Advanced

Queues and events let parts of the system work independently and handle load. But they have rules that often catch out people new to them. Messages can arrive more than once, out of order, or fail again and again. Your handlers must be ready for all three. Design for at-least-once delivery and idempotency from the start.

Message brokers (for example, Azure Service Bus) separate producers from consumers. A producer sends a message, and a consumer processes it later. This gives resilience and scalability. But the contract is usually at-least-once delivery: the same message can be delivered twice (after a retry or crash), and order is not guaranteed unless you arrange it. So handlers must be idempotent: processing the same message twice must be safe.

Two other things matter. First, handle poison messages (ones that keep failing) with retries and a dead-letter queue, so they do not block the whole queue. Second, make sure a message and the database change that goes with it cannot get out of sync. The outbox pattern solves this.

Design handlers for reality

Assumes exactly-once void Handle(PaymentRequested m) {
chargeCard(m.OrderId); // redelivery => charged twice
}

If the broker redelivers this message (which it can), the customer is charged again. At-least-once delivery makes this a real, frequent bug, not a rare one.

Idempotent handler void Handle(PaymentRequested m) {
if (alreadyProcessed(m.MessageId)) return; // dedupe
chargeCard(m.OrderId);
markProcessed(m.MessageId);
}

A duplicate delivery is detected and ignored, so the charge happens exactly once even though the message may arrive twice.

Keep data and messages consistent

Self-review checklist

Why it matters: Messaging makes systems resilient and scalable. But it is at-least-once and possibly out of order. When handlers assume otherwise, you get duplicate charges, lost updates, and stuck queues. Idempotency, dead-lettering, and the outbox pattern are what make asynchronous systems correct as well as fast.