diagram.mmd — flowchart
Message Ordering Guarantee flowchart diagram

A message ordering guarantee is the assurance that messages belonging to a logical group — such as all events for a specific user or order — are processed in the exact sequence they were produced, typically achieved by routing same-key messages to the same partition or FIFO queue.

Ordering is one of the most commonly misunderstood properties in distributed messaging. Most brokers do not guarantee global ordering across all messages — instead, they offer per-key or per-partition ordering, which is sufficient for the vast majority of business requirements.

In Kafka, ordering is guaranteed within a single partition. By using a consistent partition key (the user ID, order ID, or entity ID), all events for that entity hash to the same partition and are appended in arrival order. A single consumer reads each partition sequentially, so processing order matches production order for that key. Increasing parallelism requires more partitions — and each partition gets its own dedicated consumer slot in the Kafka Consumer Group. See Kafka Partitioning for how key assignment works.

In AWS SQS, standard queues offer best-effort ordering with no guarantees. SQS FIFO queues provide strict ordering within a message group ID (analogous to a partition key) with a throughput limit of 300 messages/second per group (3,000 with batching). The group ID is the unit of ordering.

Ordering breaks down under certain conditions: producer retries without idempotence enabled (a retried message may arrive out-of-order), consumer parallelism within a partition (avoid this), and partition reassignment during consumer group rebalances. The combination of ordering guarantees with Exactly Once Delivery provides the strongest processing semantics available in Kafka.

Free online editor
Edit this diagram in Graphlet
Fork, modify, and export to SVG or PNG. No sign-up required.
Open in Graphlet →

Frequently asked questions

A message ordering guarantee is the assurance that messages belonging to a logical group — all events for a specific user, order, or entity — are processed in the exact sequence they were produced. Most distributed brokers do not guarantee global ordering across all messages; instead, they provide per-key or per-partition ordering, which is sufficient for most business requirements.
In Kafka, a consistent partition key causes all events for the same entity to hash to the same partition, where they are appended in arrival order and read sequentially by one consumer. In AWS SQS FIFO queues, a message group ID (analogous to a partition key) enforces strict ordering within that group. Both approaches scope ordering to a logical key rather than the entire message stream.
Use per-key ordering when the correctness of processing depends on sequence — state machine transitions, financial ledger entries, inventory adjustments, or any workflow where an "update" event processed before its "create" event produces incorrect results. If your workload is entirely independent tasks with no sequencing dependency, ordering adds overhead without benefit.
A frequent mistake is enabling producer retries without `enable.idempotence=true` in Kafka — a retried message can arrive after a subsequent message for the same key, silently breaking order. Another pitfall is parallelising processing within a partition at the consumer level, which undermines the ordering guarantee. In SQS FIFO queues, choosing a message group ID with too-low cardinality creates a throughput bottleneck since ordering is enforced per group.
mermaid
flowchart LR subgraph ProducerSide E1[Event: user-A order-created] E2[Event: user-A order-updated] E3[Event: user-A order-shipped] E4[Event: user-B order-created] end PART[Partitioner\nhash partition key] E1 -->|key=user-A| PART E2 -->|key=user-A| PART E3 -->|key=user-A| PART E4 -->|key=user-B| PART PART -->|hash user-A → P0| P0[Partition 0\nordered log] PART -->|hash user-B → P1| P1[Partition 1\nordered log] P0 -->|sequential read| C0[Consumer 0\nprocesses user-A in order] P1 -->|sequential read| C1[Consumer 1\nprocesses user-B in order] subgraph Violation[Ordering Violation - Avoid] BAD[Two consumers\nreading same partition\nconcurrently] end style Violation fill:#f55,color:#fff style P0 fill:#4af,color:#000 style P1 fill:#4af,color:#000
Copied to clipboard