Retries create repeated attempts
A consumer can fail after a database commit but before recording its consumption progress. On restart it may process the same event again. Retries help eventual processing, but they also create repeated attempts.
An idempotent operation has the same intended effect when repeated. Designing for that property makes recovery safer, provided the event identity and update semantics match the business operation.
A primary key is only part of the design
A unique event identifier can prevent duplicate rows in one table. It does not automatically prevent duplicate external API calls, emails, ledger effects or increments in other tables.
For a database-local design, a deduplication record and the intended business update can be committed in the same transaction. If that transaction commits, replay finds the event recorded. If it rolls back, both the marker and the business change roll back together.
Define the failure boundaries
- Use a stable identifier for the logical event; a new identifier on each retry defeats deduplication.
- Commit consumption progress only after the durable effect succeeds.
- Handle concurrent attempts with database constraints and transaction semantics.
- Account for event ordering, corrections and late arrivals.
- Choose deduplication retention to match the possible replay window.
A simple upsert may avoid duplicate rows but still overwrite newer state with an older replayed event. Idempotency and ordering are separate concerns.
Describe the guarantee precisely
“At-least-once delivery with an idempotent database effect” is often a useful description. The guarantee has a scope: a particular effect, event identity, transaction boundary and set of failure assumptions.
Kafka transactions or another platform’s exactly-once features do not automatically include an arbitrary external database or API. Check the actual integration before extending the claim across system boundaries.
This note describes a design pattern, not an audited guarantee for a specific deployed system.