Message Ordering Guarantees
debt(d9/e7/b7/t9)
Closest to 'silent in production until users hit it' (d9). The detection_hints note automated=no, and tools listed (Datadog, Laravel Horizon) are observability/monitoring tools, not static analysis. Out-of-order processing is a runtime race condition that only manifests under concurrent load or specific timing — it is invisible until users experience corrupted state (e.g. OrderCancelled before OrderPlaced corrupting order records).
Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix identifies that fixing requires replacing queue infrastructure (SQS Standard → SQS FIFO or Kafka with partition keys), redesigning consumers for idempotency, and potentially restructuring consumer concurrency (single consumer per FIFO queue). This is not a one-file change — it touches queue configuration, producer code, consumer code, and state machine logic across multiple components.
Closest to 'strong gravitational pull' (e7). The applies_to context is queue-worker, meaning every worker, every message type, and every state transition is shaped by this architectural decision. Choosing a queue technology without ordering guarantees imposes ongoing risk on every event-driven feature added thereafter; retrofitting idempotency and ordering across existing consumers requires revisiting all business logic that processes sequential events.
Closest to 'catastrophic trap — the obvious way is always wrong' (t9). The misconception field states directly that developers assume standard queues guarantee FIFO order, but SQS Standard, RabbitMQ with multiple consumers, and most pub/sub systems do NOT guarantee order. This is the textbook catastrophic trap: the natural, obvious default (use a queue) produces silent data corruption under real-world conditions, and the correct solution (idempotency + FIFO infrastructure) is non-obvious and counter to common assumptions.
Also Known As
TL;DR
Explanation
Message ordering matters when events must be processed in sequence: UserCreated before UserUpdated, OrderPlaced before OrderShipped. Ordering options: FIFO queues (SQS FIFO, RabbitMQ with single consumer) — strict order but lower throughput. Partitioned logs (Kafka) — order within partition by key; use the entity ID as key (all order events for order 42 go to the same partition). Causal ordering: include a causality token to detect out-of-order processing. Idempotent consumers handle duplicate delivery; sequence numbers detect gaps.
Common Misconception
Why It Matters
Common Mistakes
- SQS Standard for order-dependent events — use SQS FIFO or Kafka instead.
- Kafka without partition key — messages distributed randomly across partitions lose ordering.
- Multiple consumers on a single FIFO queue — only one consumer can maintain strict ordering.
- Not handling out-of-order messages gracefully — even with ordering guarantees, implement idempotency.
Code Examples
// SQS Standard — no order guarantee:
$sqs->sendMessage(['QueueUrl' => $standardQueue, 'MessageBody' => json_encode($event)]);
// OrderCancelled may arrive before OrderPlaced
// Consumer processes cancel before the order exists — state corruption
// Kafka — order guaranteed within partition by entity ID:
$producer->produce(
partition: $this->partitionForOrder($order->id), // Same order always same partition
key: (string) $order->id,
value: json_encode($event)
);
// All events for order 42 are in the same partition — strictly ordered
// SQS FIFO with message group:
$sqs->sendMessage([
'QueueUrl' => $fifoQueue,
'MessageBody' => json_encode($event),
'MessageGroupId' => (string) $order->id, // Group per entity
'MessageDeduplicationId' => $event->id,
]);