Comparisons
Ten pairs that get conflated in real conversations. Neither column wins — what decides is the requirement. Each record leads with the confusion, because the confusion is the reason the record exists.
At-least-once vs "Exactly-once"
A provider's "exactly-once" is claimed as a delivery guarantee and read as permission to skip idempotency. Separate the two: delivery is about the transport, processing is about your business effect. A broker can deduplicate within its own window, but the moment your handler writes to a database it did not deduplicate for you.
What every real queue and webhook provider gives you: a message may be delivered more than once, and you handle it.
What you build on top of at-least-once, with idempotent handlers and deduplication — an effect observed once, not a message delivered once.
| Dimension | At-least-once delivery | "Exactly-once" processing |
|---|---|---|
| What the broker promises | The message will arrive, possibly repeatedly | Deduplication within a scope and window it defines |
| Where the burden sits | Your handler | Still your handler, for anything outside the broker |
| Typical duplicate cause | Ack lost, visibility timeout expired, consumer restart | The same, once outside the dedup window |
| Implementation | Idempotency key or natural unique constraint | The same, plus the broker's feature |
| Cost | Storing processed ids and checking them | Often reduced throughput and a constrained topology |
| Safe assumption | Assume duplicates always | Never assume the effect happened only once for free |