ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

Idempotent Receiver

The receiver-side defence: ensuring a message received twice causes only one business effect — distinct from producer-side guarantees.

Problem

An EDI broker delivers at-least-once. A partner cautiously retransmits the same DESADV after not receiving its MDN. How to avoid counting the reception twice?

Forces

  • A diligent operator pre-emptively retransmits — double arrival is normal.
  • The receiver does not always control the transport layer to dedupe upstream.
  • An Idempotency table consumed by the receiver must have a stable schema and a purge policy.
  • Detecting a duplicate costs a DB lookup — latency grows.

Solution

The receiver implements deduplication by message identifier (UNB control reference, ISA13, AS4 MessageId). On receipt, it queries an `idempotency_keys` table: if the key exists, it ACKs without re-running business logic. Otherwise it inserts the key in a transaction with processing (atomic UPSERT). The table is purged per a TTL (24h, 7d, 30d depending on the flow).

EDI implementation

In EDI, the pattern is crucial on a shared hub. Walmart MDN policies impose 5-minute retry without MDN — a naive consumer would count the same DESADV twice on reception. The idempotency table uses (`partner_id`, `message_id`) as composite PK and an index on `received_at` for purge. On Kafka, consumer-side idempotency complements producer idempotency (`enable.idempotence=true`) which only covers transmission, not business semantics.

Anti-patterns

  • Idempotency key derived from timestamp — two retransmissions 1 second apart appear distinct.
  • No TTL — the table grows indefinitely and lookups slow down.
  • Lookup outside the transaction — race condition between check and insert.
  • Idempotency only on producer side — a producer crash between send and DB commit introduces duplicates only the receiver can filter.

Sources