beginner · Interactive lab
Timeout
A timeout means the caller stopped waiting, not that the work failed. Learn what you actually know when the clock runs out, and what to do about it.
By the end: Tell apart the caller's deadline, the downstream's work, the moment the work completes, and the moment the answer arrives.
Your challenge
Start here. This lab opens with the usual reflex, and it is wrong: every timeout is treated as a failure and simply sent again. Some of those repeats create duplicate orders. Read each timeout, choose, and test.
See it happen
Watch the clock, then decide

- Order Processing → Integration Logic
- Integration Logic → Warehouse API: timed request
- Integration Logic → DLQ: parked to investigate
A call with a deadline
Order Processing sends an order. Integration Logic calls the Warehouse API and waits — but only until its deadline, the ring above it. Watch what Integration Logic knows when the ring runs out.
Learn more
Why this pattern exists
Integration Logic calls the Warehouse API and waits, but not for ever: it has a deadline. When the deadline passes without an answer, that is a timeout. A timeout tells you only that the caller stopped waiting. At that moment the Warehouse API may already have created the order, may still be processing it, or may never finish it, and from where Integration Logic stands those look exactly the same. A late answer can still arrive afterwards; it is later evidence, but the decision at the deadline has to be made without it. Two kinds of timeout behave differently. A connection timeout means the request could not reach the Warehouse API at all; in this lesson's simplified scenario that tells Integration Logic the order was not delivered, though real networks are not always that clear-cut. A response (read) timeout means the request may have arrived, but no answer came back before the deadline, so the outcome is unknown.
Order Processing sends orders through Integration Logic to the Warehouse API. Each graded case is a fixed timeline: when the caller's deadline falls, when (or whether) the Warehouse API finishes, and when its answer gets back. Time is simulated; nothing really waits and no real API is called.
- Tell apart the caller's deadline, the downstream's work, the moment the work completes, and the moment the answer arrives.
- Keep apart what the downstream actually did, what the caller knows at its deadline, and evidence that arrives later.
- Choose an action that neither guesses the outcome nor creates a duplicate: check status, retry safely, park, or fail truthfully.
The rule this lesson applies: Treat a timeout as an unknown outcome unless you know better. Report success only when the answer arrived in time, and failure only when you know the request never got through. When the outcome is unknown, a blind retry can do the work twice: check the order's status first when the downstream offers a lookup, retry when an idempotency key makes a repeat harmless, and otherwise park the order for a person to investigate. In this lesson the Warehouse API's lookup reports created, still processing, or not found, and it is always up to date: here “not found” means the original request was lost and can never be processed later, which is the only reason a retry after it is safe. Real APIs may offer no lookup, or one that lags or races a request still queued or in flight, so a plain “not found” does not make a retry safe on its own. At scale, parked unknown outcomes are usually resolved by an automated reconciliation job that checks their status later, not always by a person.

