Idempotent Consumer Pattern
IntermediateAn idempotent consumer produces the same result whether it processes a message once or multiple times — the practical alternative to EOS for most use cases.
Overview
Even with at-least-once delivery, correct behaviour is achievable by making consumers idempotent. Common techniques include a deduplication table keyed by message ID or using database unique constraints.
Deduplication with a Processed Messages Table
Store message IDs in a processed_messages table. Check before processing and skip duplicates.
@Service
@Transactional
public class IdempotentOrderConsumer {
@Autowired ProcessedMessageRepository repo;
@Autowired OrderService orderService;
@KafkaListener(topics = "orders")
public void handle(ConsumerRecord<String, Order> record) {
String msgId = record.topic() + "-" + record.partition() + "-" + record.offset();
if (repo.existsByMessageId(msgId)) return; // already processed
orderService.processOrder(record.value());
repo.save(new ProcessedMessage(msgId, Instant.now()));
}
}Key Points to Remember
- 1Idempotent consumer: same result whether message processed once or N times
- 2Track processed message IDs (topic-partition-offset) in a deduplication table
- 3Unique DB constraint on business key is a simpler alternative
- 4Clean up old dedup entries periodically
- 5Prefer idempotent consumers over EOS — simpler and faster
Interview Questions
Sign in to ask AriaWhat does it mean for a Kafka consumer to be idempotent?
How do you implement an idempotent consumer without using Kafka transactions?
What are the trade-offs between at-least-once + idempotent consumer vs exactly-once semantics?
How would you clean up old deduplication records in a high-volume system?
Can a consumer be idempotent when it calls an external API that is not idempotent itself?
Ask Aria about Idempotent Consumer Pattern
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.