← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Exactly-Once Delivery

Messaging Advanced
debt(d9/e7/b7/t7)
d9 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'silent in production until users hit it' (d9). The detection_hints field explicitly states automated: no, and the code_pattern hint (initTransactions|beginTransaction) only tells you the feature is being used, not whether it's correctly configured end-to-end. A missing transactional consumer or network partition will silently produce at-least-once or at-most-once semantics in production — duplicate or lost messages only manifest under failure conditions that are invisible during normal operation.

e7 Effort Remediation debt — work required to fix once spotted

Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix mentions Kafka transactions, outbox pattern, and idempotent consumers as alternatives. Switching from a broken exactly-once assumption to a correct architecture (either true transactional Kafka or outbox + idempotent consumer) requires changes to producers, consumers, and often the persistence layer across multiple services. This is not a single-file fix and typically spans the entire messaging pipeline.

b7 Burden Structural debt — long-term weight of choosing wrong

Closest to 'strong gravitational pull' (e7 → b7). The applies_to covers cli and queue-worker contexts broadly. Once a system is architected around exactly-once semantics (or incorrectly assumes them), every downstream consumer, producer, retry strategy, and failure-handling path is shaped by that choice. Changing the delivery guarantee affects every component that reads or writes to the message broker.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The misconception is explicit: developers commonly believe enabling Kafka idempotence achieves exactly-once end-to-end, but without a transactional consumer it is still at-least-once. Additionally, network failures make true exactly-once impossible across distributed systems. This contradicts the intuitive reading of the feature name and Kafka's own idempotent producer documentation, making it a serious trap that experienced developers commonly fall into.

About DEBT scoring →

TL;DR

Exactly-once delivery ensures each message is processed exactly once — achievable only with coordination between broker and consumer using transactions or idempotent producers.

Explanation

True exactly-once requires: idempotent producer (Kafka enable.idempotence=true), transactional producer (write + offset commit in one DB transaction), and transactional consumer. Kafka: exactly-once via transactions — producer writes and commits consumer offsets atomically. Cost: lower throughput, higher latency. Alternatives: at-least-once + idempotent consumer (practically equivalent, more portable). Exactly-once semantics (EOS) in Kafka: enable.idempotence=true + transactional.id + isolation.level=read_committed. RabbitMQ: no native exactly-once — use outbox pattern + deduplication. Most real-world systems use at-least-once + idempotency.

Common Misconception

Exactly-once delivery is always achievable — it requires both the broker AND consumer to support transactions. Without transactional consumers, at-least-once + idempotency is the realistic option.

Why It Matters

Understanding exactly-once vs at-least-once helps choose the right architecture — exactly-once is needed for financial transactions; at-least-once + idempotency works for most other cases.

Common Mistakes

  • Enabling Kafka idempotence without transactional consumer — still at-least-once end-to-end.
  • Using exactly-once where at-least-once + idempotency is simpler and sufficient.
  • Not understanding that network failures make true exactly-once impossible across systems.

Code Examples

✗ Vulnerable
// Claimed exactly-once but not transactional end-to-end:
$producer->send($topic, $message); // Idempotent producer
$consumer->process($message); // Not transactional — can fail after produce
✓ Fixed
// Kafka transactional exactly-once:
$producer->initTransactions();
$producer->beginTransaction();
try {
    $producer->send($outputTopic, $result);
    $producer->sendOffsetsToTransaction($offsets, $consumerGroupId);
    $producer->commitTransaction();
} catch (Exception $e) {
    $producer->abortTransaction();
}

Added 23 Mar 2026
Views 64
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 2 pings F 1 ping S 1 ping S 2 pings M 0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 10 Perplexity 8 ChatGPT 6 Google 6 SEMrush 5 Scrapy 5 Unknown AI 3 Ahrefs 3 Claude 1 Bing 1 Meta AI 1
crawler 45 crawler_json 3 pre-tracking 1
DEV INTEL Tools & Severity
🔵 Info ⚙ Fix effort: High
⚡ Quick Fix
Use Kafka transactions for true exactly-once. For most cases: at-least-once + idempotent consumer is equivalent and simpler. Use outbox pattern for DB-to-broker exactly-once.
📦 Applies To
cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
initTransactions|beginTransaction
Auto-detectable: ✗ No
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: High Context: File Tests: Update


✓ schema.org compliant