Message Ordering Guarantees Explained
Message ordering guarantees explained for distributed systems
Ordering is often assumed but rarely guaranteed. This post breaks down what ordering means in Kafka and how to preserve it in Spring Boot consumers.
Prerequisites
- Kafka cluster
- Java 17+ with Spring Boot
- Understanding of partitions and consumer groups
What ordering actually means
Ordering is always scoped to a partition or queue. Once you introduce parallelism, you trade throughput for ordered processing.
- Single partition: total order for the stream.
- Multiple partitions: order is preserved per key, not globally.
- Multiple consumers: order is preserved per assigned partition, not across the group.
Enforcing ordering with partition keys
Ensure that related events share the same key so they land in the same partition.
1
kafkaTemplate.send("payments", paymentId, payload);
Control consumer concurrency
Spring Kafka allows concurrent listeners. For strict ordering, set concurrency to 1 and use manual acknowledgments.
1
2
3
4
5
@KafkaListener(topics = "payments", groupId = "payments-service", concurrency = "1")
public void onMessage(String payload, Acknowledgment ack) {
processPayment(payload);
ack.acknowledge();
}
Dealing with retries
Retries can break ordering when failed messages are retried out of sequence. Prefer a retry topic strategy to maintain ordering within each partition.
Things to remember
- Ordering is partition-scoped, not global.
- Use consistent partition keys to preserve business ordering.
- Limit consumer concurrency when strict ordering is required.
This post is licensed under CC BY 4.0 by the author.