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.