Skip to main content
Message Queueslesson 2 of 4 · 3 min read

Delivery Guarantees

Three guarantees

Every queue makes you choose a delivery guarantee, and your choice decides what your consumer code has to survive.

At most once is fire and forget. The broker hands your message over once and never tries again, so a consumer that crashes halfway through loses it.

That sounds unacceptable until you price it for something like metrics, where losing one point in ten thousand is invisible and the throughput you gain is real.

At least once is what you will run in production. Your consumer does the work and then acknowledges the message, and if that acknowledgement never arrives, because the consumer crashed or simply ran slow, the broker sends it again.

Nothing is lost, and the same message can arrive twice. A consumer that crashed after sending the email but before acknowledging will send that email again.

Read the real contract there: your consumer must be idempotent, meaning that handling the same message twice leaves things exactly as handling it once would. You get that from a deduplication key, checking a message identifier against a table of what you have already processed, or from writes that are naturally safe to repeat.

Exactly once, and why you cannot buy it

Treat exactly once as the guarantee everybody wants and almost nobody can buy. Inside one system it exists, and a broker can consume, process and produce as a single atomic step within its own world.

The moment your consumer touches anything outside, an email API, a payment processor, another database, no broker can make that side effect happen exactly once.

Build the achievable version instead: at least once delivery plus idempotent processing, which produces exactly once effects. When somebody claims exactly once end to end, ask what happens if the process dies between the side effect and the acknowledgement. That question has ended a lot of vendor meetings.

the shape of it
BrokerConsumerWork doneDone twice1. deliver2. process3. ack4. no ack: again5. make it safe
step 1 of 5
At-least-once means the ack can be lost, so the same message arrives twice.

Worked example

Sam's team processes payment captures from a queue with at-least-once delivery. One Tuesday a deploy makes the consumer take 45 seconds per message, past the queue's 30-second visibility timeout, so the broker assumes each consumer died and redelivers. Every capture runs twice, and 118 customers are double-charged in 20 minutes before the pager fires. The refunds take a day; the postmortem takes longer. The fix is idempotency, enforced by the database: a captures table with a UNIQUE constraint on payment_intent_id, inserted in the same transaction as the capture record. Redelivered messages now hit constraint violation 23505, log a duplicate-skip metric, and ack cleanly. The team reruns the slow-consumer scenario in staging and watches 200 redeliveries produce zero double charges, which is the test that should have existed the first time.