At-Least-Once vs At-Most-Once vs Exactly-Once: Where to Use Each?
At-least-once delivery means every message arrives one or more times, so duplicates are possible. At-most-once means every message arrives zero or one time, so drops are possible. Exactly-once means each message takes effect one time, and it is built from at-least-once delivery plus deduplication or transactions. Kafka and Amazon SQS standard queues deliver at least once by default. The choice is made per flow, not per platform: a payment charge and a typing indicator in the same product need different guarantees.
At-least-once delivery
The broker, the service that stores and forwards messages, keeps a message until the consumer acknowledges it. The consumer processes the message first and acknowledges second. If the consumer crashes between those two steps, the broker redelivers, and the message is processed twice.
The consumer must therefore be idempotent, which means that processing the same message twice has the same effect as processing it once. The usual tools are an idempotency key, a unique id carried by each message, and a dedupe store that remembers processed keys for a bounded window, for example 24 hours. A database unique constraint on the key turns a duplicate insert into a rejected no-op.
Use at-least-once for inventory reservations recorded as ledger rows, analytics counters with commutative updates, and feed fan-out merged by event id. It is the default for any flow where losing a message is worse than seeing it twice.
At-most-once delivery
The consumer acknowledges the message before or as it starts processing. If the consumer crashes during processing, the message is gone. There is no retry, no dedupe store, and no coordination, so this is the lowest-latency and lowest-cost option.
Use at-most-once for signals where a miss is invisible or is corrected by the next refresh. Push notifications that a later app open will replace, typing indicators in chat, presence beacons, and sampled real-time metrics all fit. A financial event never fits.
Exactly-once delivery
No network can deliver a message exactly once, because a lost acknowledgment always forces a choice between a retry and a possible drop. What systems provide is an exactly-once effect: the message may arrive twice, but its result is applied once. Two patterns achieve this.
Transactional outbox and inbox. The producer writes its state change and the outgoing event in one local database transaction, so the event is never lost and never sent without the change. The consumer writes its business result and a processed marker in one transaction, so a redelivered event finds the marker and does nothing.
Checkpointed stream processing. A stream processor such as Apache Flink saves its state and its input offsets together in a checkpoint. After a crash it restores the checkpoint and replays input from that offset, and it writes to sinks with transactions or idempotent upserts. Kafka offers the same inside its own ecosystem with idempotent producers and transactions. SQS FIFO queues deduplicate by message id within a 5-minute window.
Use exactly-once for money movement, ledger updates, and entitlement or quota changes. It is worth the extra latency and infrastructure only when a duplicate costs more than the coordination.
A retail flow, step by step
Consider an order pipeline with five steps, each labeled with the guarantee it needs.
Payment charge: at least once with an idempotency key. The key is derived from the order id and the attempt number. The payment gateway stores it and returns the first result on a repeat, so the card is charged once.
Inventory reservation: at least once. Reservations are rows keyed by order id and SKU with a unique constraint. A duplicate reservation is rejected by the database.
Order confirmation email: at most once. A dropped email is recovered from the orders page or by a daily reconciliation job that resends failures.
Ledger posting: exactly once. The outbox pattern moves the event from the order service, and the inbox pattern on the ledger service applies it once.
Viewing or click analytics: at least once into the log, exactly once into the warehouse. Clients publish with retries, and a checkpointed aggregation job removes duplicates before the totals are written.
Comparison table
| Aspect | At least once | At most once | Exactly once |
|---|---|---|---|
| Delivery promise | One or more deliveries | Zero or one delivery | Single effect in the sink |
| Failure behavior | Duplicates possible | Drops possible | No drops, no duplicate effects |
| Latency | Medium, retries and acks | Low | Higher, checkpoints or transactions |
| Ops complexity | Low to medium | Low | High |
| Consumer requirement | Idempotent handler, dedupe store | Tolerate loss | Transactional or idempotent sink writes |
| Best fit | Reservations, fan-out, counters | Push alerts, typing indicators, sampled metrics | Payments, ledgers, quota updates |
| Typical tools | Kafka default, SQS standard, RabbitMQ manual acks | Non-durable queues, fire-and-forget signals | Flink checkpoints, Kafka transactions, outbox and inbox |
Delivery semantics vs processing semantics
Delivery semantics describe how many times the broker hands a message to a consumer. Processing semantics describe how many times the message's effect is applied. A system can have at-least-once delivery and exactly-once processing at the same time, and that combination is what most production systems mean when they claim exactly once. Plan for reprocessing from the start: a replay of last week's events must produce the same totals as the live run.
Key Takeaways
- At least once is the default. It needs idempotent consumers, which means an idempotency key and a dedupe store or a unique constraint.
- At most once is for signals nobody will miss. No retries, no dedupe, lowest latency.
- Exactly once is an effect, not a delivery. Build it from retries plus the outbox and inbox pattern or checkpointed stream processing.
- Label each flow, not the platform. In an interview, name five steps of the pipeline and state the failure each one can accept.
Messaging and delivery guarantees are covered with diagrams in Grokking System Design Fundamentals.
Grokking the System Design Interview applies these choices to full designs such as a payment system and a notification service.
The outbox, idempotent consumer, and checkpoint patterns are explained in System Design Patterns.

GET YOUR FREE
Coding Questions Catalog

$99

$197

$72