Should you retry a booking after a timeout?
Distinguish a missing response from a failed operation.
The question
Patchwell is a fictional team that builds scheduling software. This is an authored practice case. A booking endpoint times out. An AI draft retries the POST with a new request ID. The server may have created the first booking before its response was lost.
| Observation | |
|---|---|
| 12:00:00 | Client sends request ID r1 |
| 12:00:02 | Server creates booking b7 |
| 12:00:03 | Response is lost |
| 12:00:05 | Client times out |
Authored example. Values are supplied for this case.
One user action must create at most one booking. A user may intentionally create a second booking later.
“Would you accept the retry? Explain a safe protocol and the test that proves it.”
Not saved by this site. Your browser may restore text when you navigate back.
A strong answer, step by step
Open each step in turn. This is one strong answer, not the only one.
Step 1: Keep the outcome unknown
What would you do here? Open the move you’d make.
Treat the first outcome as unknown
The strong move. It matches the supplied timeline.
Assume timeout means rollback
Tempting, but it misses something. The timeline shows the booking already exists.
See how a strong candidate says it
“The timeout proves the client lacks a response. It does not prove the server did nothing. Retrying with a new identity may create a second booking.”
Why it works: The distinction is central to the duplication failure.
Step 2: Preserve action identity
What would you do here? Open the move you’d make.
Use a fresh UUID on each retry
Tempting, but it misses something. That makes each retry appear to be a new action.
Reuse the action key with a server guarantee
The strong move. Repeated transport attempts map to one operation.
See how a strong candidate says it
“Create an idempotency key for the user action and reuse it for retries. The server must atomically associate the key with the operation and its result; a client-only flag cannot protect a server from duplicate requests.”
Why it works: The guarantee must hold where the booking is created.
Step 3: Test the lost response
What would you do here? Open the move you’d make.
Test creation before response loss
The strong move. It reproduces the failure window.
Only test a request that never reaches the server
Tempting, but it misses something. No booking exists in that easier failure case.
See how a strong candidate says it
“I would simulate creation followed by a lost response, then retry with the same key. Assert one booking exists and the result identifies b7. Also send two simultaneous requests with that key.”
Why it works: A happy-path retry does not test the dangerous partial outcome.
Step 4: Bound the guarantee
What would you do here? Open the move you’d make.
Claim all side effects now happen exactly once
Tempting, but it misses something. The case does not establish that guarantee.
Define payload matching and key lifetime
The strong move. The protocol needs a clear scope.
See how a strong candidate says it
“The same key with a different payload should be rejected. Separate intended bookings need separate keys. I would define retention and timeout behavior with the team; idempotency is not a promise that every dependency executes exactly once.”
Why it works: It keeps action identity and delivery semantics precise.
The answer, in short
- Decision
- Reject the new-key retry and define server-side idempotency.
- Because
- The first operation may have committed before the client timed out.
- What would change it
- If the endpoint could prove no first operation occurred, a new action would be safe.
Common traps
- Equating a timeout with no write.
- Claiming a client flag enforces a distributed guarantee.
Check your answer
- Did you preserve uncertainty after timeout?
- Did you keep one identity across retries?
- Did you test concurrent attempts and a lost response?
- Did you define where the guarantee ends?
Last reviewed Nov 10, 2026