Messaging, Events and Email Systems · Asynchronous Workflows

Delivery Guarantees and Idempotent Consumers

At-most-once, at-least-once and 'effectively once' processing.

Brokers usually provide at-least-once delivery: after crashes, timeouts or rebalances, messages can be redelivered. At-most-once risks loss. End-to-end exactly-once is achieved in practice by at-least-once delivery plus idempotent consumers: deduplicate by message/event ID in the same transaction as the side effect (an inbox table), or make operations naturally idempotent (upserts, conditional updates).

-- Inbox pattern: process each event once
BEGIN;
  INSERT INTO processed_events (event_id) VALUES ('evt_123')
    ON CONFLICT DO NOTHING;            -- 0 rows → already processed → COMMIT and ack
  UPDATE accounts SET balance = balance + 500 WHERE id = 42;
COMMIT;
-- ack the message only after COMMIT

Common pitfalls

  • Acknowledging before processing (loss on crash).
  • Dedup tables without retention policies.
  • Non-idempotent side effects like sending emails twice.

Key points

  • Assume at-least-once
  • Idempotent consumers via inbox/dedupe
  • Ack after commit

Further reading: microservices.io: Idempotent consumer

Practice questions

Why must a consumer acknowledge only after committing its work?

Answer

If it acks first and crashes, the broker won't redeliver and the work is lost; acking after commit risks duplicates instead, which idempotency handles.

How can an operation be naturally idempotent?

Answer

By setting absolute state (UPSERT, SET status = 'shipped') or using conditional updates, rather than relative changes like increments.

Open in the app to mark lessons complete, take notes and track your progress.