Spring Kafka and exactly once delivery guarantee
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Apache Kafka is a distributed streaming platform that has three core capabilities: Publishing and subscribing to streams of records, storing streams of records in a fault-tolerant way, and processing streams of records as they occur. Kafka is widely used across engineering teams for its high throughput and resilience to node failures, making it an excellent choice for large-scale event processing applications.
Introducing Spring Kafka
Spring Kafka brings the simple and typical Spring template programming model to Kafka. Developed under the Spring umbrella, it provides a high-level abstraction for Kafka-based messaging solutions. Spring Kafka simplifies the use of Kafka by enabling the development of message-driven microservices and stream processing applications in a loosely coupled manner. It integrates deeply into the Spring ecosystem, including the Spring Boot framework, to provide configuration and abstraction layers that make working with Kafka considerably simpler.
Exactly Once Delivery
In the context of distributed systems, message delivery semantics can generally be divided into three categories: at-most-once, at-least-once, and exactly-once. "Exactly once" delivery semantics ensures that a message is delivered once and only once to the end consumer, even in the case of failures. This is the holy grail of messaging systems as it ensures reliable communication without duplication.
Implementing exactly once delivery is challenging due to potential duplicates on retries and the complexity of tracking acknowledges. Kafka, since version 0.11, supports exactly-once semantics in the context of message production and consumption.
How Exactly Once Semantics are Implemented in Kafka
Kafka’s exactly-once semantics is implemented through its idempotent producer and transactional APIs. The idempotent producer ensures that messages are not duplicated when they are sent to a Kafka topic, while the transactional API allows applications to write multiple messages across several partitions atomically.
To achieve exactly once semantics when producing to Kafka using Spring Kafka, you can follow these steps:
- Enable Idempotence: Configure the producer setting
enable.idempotentto true. - Use Kafka Transactions: Enabled by setting up the
transactional.idin the producer configuration, which ensures that a group of messages across multiple partitions can be committed or aborted together. - Transaction Coordinator: Kafka uses a Transaction Coordinator to manage the transaction states, which is an internal Kafka mechanism.
Implementing Exactly Once in Spring Kafka
| Implement Terminology | Spring Configuration |
| Idempotent producer | producerProperties.put("enable.idempotence", true); |
| Transactional producer | producerProperties.put("transactional.id", "tx-id"); |
| Consumer offset handling | Managed in the Kafka transaction |
Code Example: Spring Kafka Exactly Once
This code snippet demonstrates a simple producer and consumer application where the producer sends messages using a transaction, and the consumer processes these messages. Note that the actual message could require further integrity checks to ensure duplication hasn't occurred at other parts of the system.
Pros and Cons of Exactly Once Semantics
Advantages:
- Eliminates the complexity of handling duplicates at the consumer level.
- Simplifies consumer logic as each message needs to be processed only once.
Disadvantages:
- Potential for increased latency due to overhead of maintaining and checking transactions.
- More complex configuration and resource management.
Conclusion
Implementing exactly once semantics in Kafka using Spring Kafka requires a careful setup of producer and consumer configurations. While it ensures reliable processing of messages, it can introduce additional overhead. Depending on the use case, it is crucial to evaluate whether the benefits of exactly once semantics outweigh the potential drawbacks like latency and system complexity. For many critical applications, however, exactly once delivery is essential for data consistency and integrity, making this setup vital.
Related reading
- Spring kafka and Kafka Cluster
- Spring Kafka and Kafka Streams
- Spring Kafka asynchronous send calls block
- Spring Kafka Auto Commit Offset In Case of Failures
- Spring Kafka Consumer/Listener Group
- Spring Kafka multiple consumer for single topic consume different messages
- Spring Kafka configure number of partitions for topic
- Spring kafka Consume multiple Message types in one consumer

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.