Idempotencyeasy0-2 years

A teammate says "let's just make the payment queue exactly-once so we don't need to worry about duplicate charges." What's wrong with that plan, and what do you build instead?

Every real messaging system — Kafka, SQS, RabbitMQ, even a plain HTTP client with a retry — delivers at least once, not exactly once, and that isn't a configuration you can turn up: it's what happens whenever a consumer can crash between doing the work and acknowledging it, or a network can drop an acknowledgement. "Exactly once" end to end between two independently-failing systems isn't a feature some vendor forgot to build; there's a classical argument (the Two Generals Problem) for why no finite exchange of messages over a channel that can lose messages ever lets both sides become certain the other received the last message. So the fix isn't to make delivery exactly-once — it's to make redelivery harmless. That means the consumer remembers what it already processed and skips the duplicate: not a lookup-then-write (too slow to close the race), but an atomic claim — an INSERT into a table with a unique constraint on the payment id — where the database itself decides who wins and the loser gets a constraint violation instead of charging the card twice.

The lesson behind it →