Retries, Idempotency, Ordering, Replay, and Failure Handling
Goal
Make asynchronous delivery and recovery behavior explicit rather than relying on optimistic happy paths.
The Short Version
Reliable integration assumes messages can be delayed, duplicated, reordered, poisoned, and replayed.
Retries need bounded attempts, backoff, jitter, time budgets, and classification of transient versus permanent failure. The important architecture move is to make the boundary explicit before selecting a cloud feature. A feature can automate a decision, but it cannot decide the organization's risk tolerance, ownership model, or acceptable failure behavior.
Use this section as a decision tool. Name the actor or producer, the protected or affected resource, the contract between them, the conditions under which the action is allowed, and the evidence that will show whether the design worked.
Mental Model
Show a message lifecycle through delivery, processing, acknowledgement, retry, dead-letter, repair, replay, and reconciliation.
flowchart LR
N1["Producer intent"] --> N2["Contract"] --> N3["Delivery mechanism"] --> N4["Consumer"] --> N5["Outcome"] --> N6["Failure evidence"]
Read the diagram from left to right, then review it from right to left. The forward pass explains how work succeeds. The reverse pass asks whether an operator can trace an outcome back to its initiating identity, input, policy, route, or contract.
Architecture Decisions
| Decision dimension | Question to make explicit |
|---|---|
| Intent | Is this a query, command, notification, fact, stream, or process step? |
| Coupling | Must the producer wait for a named consumer? |
| Delivery | What can be duplicated, delayed, reordered, or lost? |
| State | Where is process progress, correlation, and replay position stored? |
| Change | How do contracts evolve without forcing coordinated releases? |
The answers should be recorded with the workload design. If the answer is merely "the platform default," the team has discovered an assumption, not completed an architecture decision.
Core Ideas
Retries need bounded attempts, backoff, jitter, time budgets, and classification of transient versus permanent failure
Retries need bounded attempts, backoff, jitter, time budgets, and classification of transient versus permanent failure. Make the owner, boundary, failure behavior, and evidence explicit. That turns the concept from a configuration choice into a design decision that another team can review and operate.
Idempotency may use stable operation identifiers, deduplication records, conditional writes, or state-machine rules
Idempotency may use stable operation identifiers, deduplication records, conditional writes, or state-machine rules. Make the owner, boundary, failure behavior, and evidence explicit. That turns the concept from a configuration choice into a design decision that another team can review and operate.
Ordering usually has a limited scope; replay and dead-letter recovery require version-tolerant consumers and operational runbooks
Ordering usually has a limited scope; replay and dead-letter recovery require version-tolerant consumers and operational runbooks. Make the owner, boundary, failure behavior, and evidence explicit. That turns the concept from a configuration choice into a design decision that another team can review and operate.
Provider Lenses
AWS provides API Gateway, SQS, SNS, EventBridge, Kinesis, and Step Functions among its implementation choices. Azure provides API Management, Service Bus, Event Grid, Event Hubs, Logic Apps, and Durable Functions. Choose first among request-response, work queue, publish-subscribe, event routing, durable stream, and workflow semantics; then map those semantics to a provider service.
Provider lenses are useful for implementation planning, but they should come after the provider-neutral decision. This keeps the reasoning portable and makes differences in defaults, scope, and operational responsibility easier to detect.
Example: Applying the Decision
A payment-completed event is delivered twice, then an older inventory event arrives after a newer one.
Keep checkout validation synchronous, submit accepted orders durably, orchestrate payment and inventory when the business needs visible process state, publish outcome events for fulfillment and notifications, and make every state-changing consumer idempotent.
A review should finish with named owners, a testable success path, expected failure modes, and observable evidence. That is more useful than a diagram that only proves the components can connect.
Common Mistakes
Assuming broker delivery guarantees make business effects exactly once. It hides a boundary or enlarges the impact of failure, so record the safer alternative in the design.
Requiring global ordering when only per-order ordering is necessary. It hides a boundary or enlarges the impact of failure, so record the safer alternative in the design.
Creating a dead-letter queue without ownership, alerting, repair, or replay procedures. It hides a boundary or enlarges the impact of failure, so record the safer alternative in the design.
If Someone Asks You
How do you design an integration that survives duplicate and out-of-order delivery?
A clear answer is:
Reliable integration assumes messages can be delayed, duplicated, reordered, poisoned, and replayed.
I would then show the decision path, the responsibility boundary, and the evidence used to review it. That explanation connects the technical mechanism to its architecture purpose.
What You Should Remember
Reliable integration assumes messages can be delayed, duplicated, reordered, poisoned, and replayed.
Questions to Check Your Understanding
Which properties make an operation idempotent?
Why should ordering scope be minimized?
What operating capabilities make dead-letter handling useful?