A stock reservation appears twice. A customer receives the same confirmation again. An automation reports a timeout, so someone presses Retry—and now nobody knows whether the first attempt worked.
Those are hypothetical situations, not client stories. They illustrate a question worth settling before buying or building a business automation: if this action runs again, will it repeat the work or recover the result?
The short answer is to give each intended action a stable identity, define how the receiving system handles repeats, and provide a way to investigate uncertain outcomes. This is often called an idempotency contract: retrying the same intended action must not add another business effect.[2] A retry setting alone is not that agreement.
Why a timeout can lead to duplicate actions
Imagine a booking app asking an inventory service to reserve a place. The service records the reservation, but its reply never reaches the app. From the app's side, that can look like failure even though the business action succeeded. AWS describes this ambiguity in its discussion of retry side effects: after a missing response, the caller must decide whether to reconcile the result or risk repeating an operation.[2]
There is another route to repeated work: delivery itself. Amazon SQS documents that a standard-queue message can be received again and tells application builders to make repeated processing safe.[3] That is a specific delivery contract, not evidence that every queue behaves identically.
For a buyer, the useful distinction is between an attempt and an action. Several attempts may belong to one intended reservation. Two deliberate reservations, even with identical details, are two actions. A timeout is not proof that nothing happened.
What an idempotency key should mean in your brief
An idempotent operation can be retried without additional side effects.[2] In plain language: ask again for the same action without accidentally doing it again.
A common API contract uses a caller-provided identifier, often called an idempotency key. AWS explains why a unique client request identifier can express intent more reliably than guessing from matching request contents: two identical requests might genuinely be asking for two resources.[2]
Consider these proposed rules for the hypothetical booking workflow:
| Situation | Required behavior to agree before implementation |
|---|---|
| Same action identifier, same reservation details | Return the known outcome, or a defined processing status; do not create another reservation. |
| Same identifier, changed reservation details | Reject the mismatch or send it for explicit resolution; do not silently reinterpret it. |
| A genuinely new reservation with identical details | Use a new action identifier so legitimate repeat business remains possible. |
| No reliable evidence of the first outcome | Show an uncertain state and investigate before authorizing a fresh action. |
This table is an original acceptance framework, not a description of an installed application. Decide the identifier's scope too: tenant or account, operation type, and action identity. A key is not an authorization credential; it should not let one customer's request retrieve another customer's result.
Check the provider's retry contract and retention window
Stripe is a useful concrete example, not a recommendation to buy a payment service. Its API reference, checked on 26 October 2026, distinguishes API v1 and v2 retry behavior. For API v1, it documents saving the first status code and response body after endpoint execution begins; subsequent requests with the same key return that saved response, including a 500 error response.[1]
The same reference says API v1 keys may be removed after they are at least 24 hours old, and reuse after pruning creates a new request. It also describes parameter comparison and cases where validation failure or a concurrent execution conflict does not save an idempotent result.[1]
Those details matter more than a feature checkbox. Do not copy a provider's retention window into your own design without comparing it with your longest possible replay: an overnight outage, a delayed job, or an operator restarting old work. AWS likewise explains that suitable identifier retention varies by service and resource.[2]
Before accepting an integration, ask which endpoint and API version support the key, what is retained, when that protection expires, and how to query the authoritative result. Do not assume an arbitrary request header creates server-side protection. Stripe also advises against putting sensitive data such as email addresses or personal identifiers in idempotency keys.[1]
Why a key alone does not solve concurrency or crashes
Now suppose the booking service checks for a key, creates a reservation, and only afterward saves the key. A crash between those steps leaves a reservation without its repeat-protection record. Two workers checking at the same time create another risk.
AWS explicitly calls for recording the token and the related mutations as an atomic, all-or-nothing operation in the service design it describes.[2] For the buying brief, ask the developer to explain the transaction boundary and concurrent-request behavior—not just show that a second sequential button click is blocked.
A separate email service, payment provider, or shipping system may sit outside that database transaction. Treat each such boundary as another contract to inspect. As a design recommendation, keep durable workflow state, use the downstream provider's supported action identity where available, and reconcile uncertain downstream outcomes. A local 'processed' flag does not by itself prove what happened in another service.
Avoid an unqualified 'exactly once' promise. Ask: exactly which effect, across which systems, for how long, and under which failure conditions?
A lost-response test to request before release
Here is a hypothetical acceptance scenario to take into a development review:
- A user confirms one reservation. The app creates and durably keeps one action identifier before its first attempt.
- The receiver commits the reservation and its repeat-protection record within the agreed transaction boundary.
- The response is deliberately lost in a controlled test. The app displays 'confirmation pending' rather than inviting a new booking.
- The app retries the unchanged action with its original identifier. The receiver returns the original reservation outcome under the agreed contract.
- If the receiver's outcome remains unknown, the workflow moves to an exception queue with an owner and the original identifier. It does not quietly generate a new identity.
This sequence is a proposed test, not a test result. No booking system, payment, message delivery, concurrent worker or crash-recovery implementation was executed for this article. It also does not replace authorization checks or permission to send a message or charge a customer.
Safe-retry checklist for an automation proposal
Use the following questions to make a proposal comparable. Ask for an observable demonstration or an explicitly documented limitation for each answer.
- Business effect: What must not happen twice—reservation, charge, dispatch, or customer notification? Separate these effects rather than treating 'the workflow' as one opaque step.
- Identity: Who creates the identifier, where is it saved before the first attempt, and how does it survive a restart? Does a manual replay reuse it?
- Mismatch: What happens when the same identifier arrives with changed details? Can a legitimate new action still proceed with its own identity?
- Concurrency: What happens when two workers process the same action together? Require a controlled overlap test, not only sequential retries.
- Crash recovery: Test failure before commit, after commit but before response, and between local work and an external effect. Which durable evidence survives?
- Retry budget: Which failures are eligible, how long can retries continue, and when does a person take over? Agree bounded attempts, delay policy and an overall deadline; these are design choices, not guarantees of success.
- Retention: Can an old replay outlive the deduplication record? What prevents an expired or uncertain action becoming fresh work without review?
- Evidence: Can support find the action identifier, attempts, authoritative result and resolution without exposing credentials or unnecessary personal data?
- Recovery owner: Who investigates uncertainty, who may authorize a new action, and what evidence must they check first?
For example, a proposal that says 'three retries' has not answered whether the third attempt can create another reservation. A proposal that names the action identity, receiving contract, expiry behavior and lost-reply test gives you something concrete to review.
Start with the work you cannot afford to repeat
You do not need to specify every database detail to write a useful brief. Pick one business action. Describe what a duplicate would mean, how long uncertainty is tolerable, and who should resolve it. Then ask the implementer to demonstrate the failure paths before release.
For more planning context, browse the CodeCanvasDigital insights. To discuss a website, web application or automation requirement, use the project brief on the CodeCanvasDigital website. Describe the workflow and the effect that must not repeat; leave out passwords, access tokens and sensitive customer records. The helper lets a visitor request an email draft. It does not confirm that an email app opened, that a message was sent, or that an inquiry was received.
Sources
[1] https:/
[2] https:/