Idempotent Consumption — Manufacturing Exactly-Once at the Receiver

Post 2 ended with the only honest promise available: at-least-once delivery, duplicates included. This post builds the receiver that makes duplicates harmless and disorder survivable — the dedup store, the effect-level idempotency that outranks it, and the versioned-state techniques that let events arrive in any order and still converge on the truth. This is where "exactly-once" actually gets manufactured.

The techniques here are the webhook-shaped versions of old friends from the Fintech Engineering Handbook’s idempotency chapter and distributed systems generally — applied at the integration boundary where you control only one side.

Layer one: event-ID deduplication

Every well-designed webhook event carries a unique event ID, and the first defense is the obvious one: keep a store of processed IDs; on arrival, attempt to record the ID; if it already exists, acknowledge and stop. Three details separate the robust version from the naive one. The check must be an atomic claim — a read-then-process-then-write sequence has a race where two concurrent deliveries of the same event both pass the read; the correct shape is an atomic insert-if-absent (unique constraint, conditional put) that exactly one delivery wins. Claim at the right moment — claim-then-process risks a crash after claim leaving the event marked done but unprocessed; the stricter pattern claims within the same transaction as the effect (next section) or records the claim only on completion while tolerating the resulting re-execution window. Retention is part of the contract — dedup entries can expire only after the provider’s published retry horizon (post 2) plus your reconciliation window; expiring them in hours to save storage reopens the duplicate door exactly when late retries walk through it.

Layer two: idempotent effects — the stronger property

Event-ID dedup treats delivery as the thing to make unique. The deeper discipline makes the effect idempotent, so even a redelivery that slips the dedup net (or a replay you trigger deliberately during recovery — post 8) lands harmlessly:

Layer three: surviving disorder

Unordered delivery (post 1) means customer.updated can arrive before customer.created, or two updates can arrive reversed. Ordering recovery has a toolkit, chosen by how much the payload can be trusted:

One concurrency note spans all three layers: process events for the same resource serially (partition your workers by resource ID — post 5’s queue makes this natural), because most “ordering bugs” are actually two handlers interleaving on one aggregate.

The takeaway: the receiver manufactures exactly-once in layers — atomic event-ID claims with retention outliving the retry horizon, idempotent effects (absolute operations, the effect-plus-ID-in-one-transaction pattern, idempotency keys on every downstream call) as the stronger guarantee beneath, and disorder survival via version-stamped applies, fetch-on-event convergence, bounded parking for prerequisites, and per-resource serialization. Dedup is the door lock; idempotent effects are the vault; together they turn the provider’s loose promises into your strict ones.

Key takeaways

Further reading

Sources & References

the property that makes retries and replays safe
the concurrent-delivery bug the atomic claim prevents