Decision guide

At-Most-Once vs At-Least-Once vs Effectively-Once

What delivery guarantee do you need, and how do you get it?

Side by side

CriterionAt-most-onceAt-least-onceEffectively-once
DuplicatesNeverPossibleAbsorbed
Message lossPossibleNo (until retries exhausted → DLQ)No
MechanismAck first / fire-and-forgetAck after processing, retriesInbox/dedupe, idempotent writes, Kafka EOS
ComplexityLowestLowMedium–high
External side effectsMaybe lostMaybe duplicatedNeed idempotency keys at destination

When to choose each

At-most-once

Send/ack before processing; never redeliver.

Choose when

  • Metrics and telemetry
  • Best-effort notifications

Avoid when

  • Business events, payments

At-least-once

Retry until acknowledged; ack after processing.

Choose when

  • Most business events and jobs
  • Default for brokers

Avoid when

  • Consumers that can't tolerate duplicates

Effectively-once

At-least-once delivery + idempotent/deduplicated processing (or transactional pipelines).

Choose when

  • Payments, ledgers, inventory
  • Stream processing with transactional sinks

Avoid when

  • When duplicates are harmless (extra complexity)

Verdict

Assume at-least-once and make consumers idempotent — that yields effectively-once processing. Reserve at-most-once for data you can afford to lose, and remember that broker 'exactly-once' features stop at the broker's boundary.

Learn more

Sources