← All articles
Backend1 min read

Exactly-Once Semantics in Kafka

At-least-once delivery means duplicates. Kafka's idempotent producer and transactions let you achieve exactly-once processing when you truly need it.

S

Swapnika Voora

Author

By default Kafka gives at-least-once delivery: a retried send can produce a duplicate. For consume-transform-produce pipelines, transactions give you end-to-end exactly-once semantics.

Idempotent producer

Enabling idempotence deduplicates retries within a partition automatically.

Producer.java
props.put("enable.idempotence", "true");
props.put("acks", "all");
props.put("transactional.id", "payments-tx-1");

Wrap read-process-write in a transaction

Committing offsets inside the same transaction as the output makes the whole step atomic.

Transaction.java
producer.initTransactions();
producer.beginTransaction();
producer.send(outputRecord);
producer.sendOffsetsToTransaction(offsets, groupMetadata);
producer.commitTransaction();

Takeaways

  • Set consumers to isolation.level=read_committed to skip aborted messages.
  • Exactly-once adds latency and coordination cost — use it only where required.
  • For side effects outside Kafka, you still need idempotent writes downstream.

Exactly-once covers Kafka-to-Kafka flows; a database write in the middle still needs its own idempotency key to avoid double application.

#kafka#transactions#reliability

More in Backend