A timeout tells the caller that it did not receive a response in time. It does not tell the caller whether the server completed the operation. That distinction matters when an API creates a resource: drawing “timeout → create again” can hide the risk of duplicate work.
This tutorial models an illustrative report-generation API. It is a documentation exercise, not a production implementation or evidence of how a particular service behaves. The goal is to make the retry policy and its assumptions visible to a reviewer.
Write the contract before drawing the arrows
Assume the client sends a request key with a report creation request. The API stores a result associated with that key. A retry with the same key and payload returns the stored result instead of creating another report. This example shows one retry after a lost response, followed by a separate lookup if the client still cannot confirm the result.
That contract is a design assumption. A real service must define key scope, retention, concurrent requests, and what happens when the same key arrives with a different payload. The diagram cannot supply those guarantees on its own.
Show the ambiguous result explicitly
Rendering diagram…
View Mermaid source
sequenceDiagram
autonumber
participant C as Client
participant A as Reports API
participant R as Result store
C->>A: Create report, key K
A->>R: Save report result under K
R-->>A: Result recorded
Note over C,A: Response is lost, client reaches its timeout
C->>A: Retry same request with key K
A->>R: Look up result for K
R-->>A: Existing report result
alt Retry response arrives
A-->>C: Return existing report ID
else Retry also times out
Note over C: Stop automatic retries, outcome is unknown
C->>A: Query status for key K
A-->>C: Report ID or pending status
endThe first note matters more than another arrow labeled “error.” It says that the result was recorded but the client did not see the response. The second request therefore asks the API to resolve the same logical operation, using the same key.
The diagram uses alt for alternative outcomes and a note for the missing response. See the Mermaid sequence reference for these constructs. Arrow appearance is a drawing convention; the labels carry the protocol meaning.
Review what the diagram leaves out
This is a deliberately simplified successful lookup path. The lookup can also fail, the key can expire, and a server can crash between creating a report and storing the result. Add those cases if they are part of the decision under review. In particular, an implementation that stores the key only after performing the side effect may still duplicate work during a race or crash.
| Review question | Why it changes the picture |
|---|---|
| Is the request safe to repeat? | Some operations need deduplication or another recovery method |
| Who chooses the key? | A new key on every retry can represent a new operation |
| When is the result recorded? | A gap between the side effect and the record can permit duplicates |
| How many retries are allowed? | An unbounded loop conceals the stopping condition |
| How does the user see an unknown outcome? | “Failed” can be misleading when work may have completed |
Avoid putting a precise timeout or backoff duration into the example unless it comes from the service contract. A guessed number looks like an agreed operational requirement once it enters a design document.
Adapt the example without losing its meaning
Rename the participants first. Then replace “Create report” with the operation you are documenting, and decide whether the assumed key-based behavior actually exists. If it does not, remove the stored-result guarantee and show the recovery action the service really supports.
Keep the normal response and the unknown outcome distinct. If your application shows “Check status” after a timeout, include that state in the accompanying UI description. Do not promise that the diagram's status query will always succeed; the example assumes it succeeds so that the main ambiguity remains easy to follow.
Copy the example into the workspace, change one part of the contract, and ask a reviewer to trace the lost-response branch. If they can say whether another resource is created and what the client does next, the diagram answers its central question. For more syntax, see the sequence diagram guide.