The payment provider charges the customer, but the response disappears in transit. The application times out. Retrying risks a second charge; not retrying risks leaving the order unconfirmed. “Do it exactly once” sounds like a reasonable requirement until we ask what “it” actually means.
Exactly-once is often discussed as a transport guarantee. What the business needs is one completed effect: one payment, one reservation, one shipment.
Define the boundary of the guarantee
Some platforms can process messages transactionally within a controlled scope: consume an event, update state and publish a result. That guarantee can be valuable. It does not automatically extend to a bank, warehouse or other external system.
A message can also be processed successfully while its acknowledgement is lost, leading to another delivery. Consumers therefore need correct duplicate behaviour even when one component advertises exactly-once semantics within its own boundaries.
Idempotency belongs to the business operation
For a payment, repeated attempts can share a durable operation identifier. A provider or service with appropriate idempotency support recognises the retry and returns the result or status of the original operation instead of creating a new charge.
The duplicate check and the state change must be coordinated. Checking “have we seen this payment?” and then charging separately is insufficient when two requests arrive concurrently. A transaction, unique constraint or another correct concurrency mechanism is needed.
Emails, warehouse tasks and balance changes each have different definitions of a duplicate effect. There is no single universal checkbox for all of them.
An unknown result is not a failure
A timeout does not prove that nothing happened. Querying the status of an operation by its stable identifier is often safer than blindly issuing another command.
Safe consumption may involve a Transactional Inbox, unique business keys and idempotent handlers. Reliable publication from a database is a different concern, often handled with an Outbox. The two mechanisms complement each other.
Pay for the guarantee that matters
Not all duplicates are equally harmful. Recomputing an internal metric twice may be cheap. Charging twice or shipping twice is not. I would start with the cost of a repeated business effect and the exact scope of protection required, then choose the coordination mechanism.
Whenever an architecture diagram or product documentation says exactly-once, it should answer: exactly once what, across which boundary, under which failures?
Customers do not care how many times the broker delivered a message. They care that one order produces one charge.