At-Least-Once Delivery
also called Redelivery Semantics, Duplicate-Tolerant Delivery
The delivery guarantee that a message will arrive but may arrive more than once - the strongest practical guarantee across an unreliable boundary, which pushes the deduplication responsibility onto the receiver.
Any sender that cannot confirm receipt must choose: retry and risk a duplicate, or do not retry and risk a loss. At-least-once chooses duplicates, because for most systems a duplicate is recoverable and a loss is not.
It is the guarantee offered by essentially every message broker, webhook system and event pipeline in production, and the correct interpretation is that deduplication is the receiver's responsibility, always.
Why it matters
"Exactly-once delivery" does not exist across a network boundary, and systems that advertise it are providing exactly-once processing through a combination of at-least-once delivery plus deduplication or transactional state updates — which is a genuinely useful thing, and is not what the phrase suggests.
The practical consequence: every consumer that does not deduplicate has a latent double-processing bug. It may not have fired yet, because duplicates are rare in normal operation, and it will fire during an incident — when the broker redelivers, when a consumer restarts mid-batch, when a webhook times out after succeeding. The bug appears exactly when the system is already under stress.
Implementation patterns
- A stable, sender-generated message or delivery identifier, carried on every attempt of the same logical message, so the receiver can recognise a redelivery. Without this, deduplication is impossible and the receiver is guessing from content.
- Receiver-side deduplication with bounded retention: store processed identifiers for a window comfortably longer than the sender's maximum retry span.
- Idempotent handlers as the stronger alternative: design the effect so that applying it twice is indistinguishable from applying it once — set a state rather than increment, upsert rather than insert. Where achievable this is better than deduplication, because it needs no storage and no window.
- Deduplication in the same transaction as the effect, or the process can crash between them and reintroduce the duplicate it was preventing.
- Ordering treated as absent, since at-least-once systems generally do not preserve it under retry; use sequence numbers or version checks where order matters, and reject stale updates.
- An explicit statement of the guarantee in the documentation, with the deduplication requirement stated as an obligation rather than a suggestion.
- Monitoring duplicate rates, since a sudden rise indicates a delivery-path problem worth investigating.
Industry example
Webhook platforms — Stripe's among the most documented — publish at-least-once semantics explicitly and instruct consumers to deduplicate on the event identifier. The same guarantee underlies Kafka consumers (offsets are committed after processing, so a crash between the two redelivers), SQS, and virtually every event pipeline.
The pattern of failure is consistent across all of them: the consumer's implementer reads "at-least-once", assumes duplicates are rare enough to ignore, and ships a handler that increments a counter or sends an email. The duplicate arrives months later during an unrelated incident, and the resulting bug is attributed to the delivery system rather than to the missing deduplication.
Failure scenarios
- No deduplication in the consumer, producing double charges, double emails, double inventory decrements.
- Deduplication keyed on content rather than on a delivery identifier, so two legitimately identical events are merged into one — the opposite and equally serious error.
- A deduplication window shorter than the retry window, so a late redelivery is processed as new.
- Deduplication recorded outside the effect's transaction, leaving a crash window.
- Assuming ordering, so a retried older message overwrites a newer state.
- Unbounded deduplication storage, which becomes an operational problem of its own.
- A receiver that acknowledges before processing, converting at-least-once into at-most-once and silently losing messages — usually done to fix a timeout, and rarely recognised as a semantic change.
Trade-offs
At-least-once pushes real work onto every consumer, and consumers vary in competence — a provider choosing this guarantee is choosing to distribute a correctness obligation across parties it does not control. The alternative, at-most-once, removes that work and loses messages, which is acceptable only for genuinely disposable data such as sampled telemetry.
Making a handler idempotent is sometimes easy and sometimes requires restructuring the effect itself — turning an increment into an idempotent state transition, or introducing a natural key where none existed.
The trade is duplicate handling versus message loss, and for anything financial, transactional or user-visible the choice is not close. The engineering question is never "how do I avoid duplicates" but "where does deduplication live and what is its window."
Interview question
"Our webhook handler creates a shipment. It has worked for two years and last Tuesday we shipped four hundred duplicate orders during a provider incident. Tell me what happened, whose bug it is, and give me the fix — plus the reason your fix survives a crash between receiving the event and writing the shipment."