Stop duplicate actions when an automation retries
A practical guide and interactive lab for repeated requests, lost confirmations and changes that should never pass as a retry.
Try the tool
Keep the identity of the intended operation, distinguish uncertainty from failure, and verify an ambiguous result before authorizing another action.
More attempts. More actions?
Try a fictional request to prepare 2 units of an order. Compare what the sender knows with what happened at the destination.
- Operation key
- DEMO-OP-017
- Fictional reference
- DEMO-ORDER-017
- First request → retry
- 2 → 2 units
Ready to try
Send the first request and watch both counters.
Available confirmation: Not available yet
0 attempts; 0 fictional actions; 0 verifications.Name the action you cannot afford to repeat
Start with a single business action: adding an order, sending a notice or creating a delivery task. Write down where its result becomes visible and who notices a duplicate. A workflow can complete successfully while still producing an extra row.
Our synthetic example is a fictional workshop preparing two units for order DEMO-ORDER-017. The simulator sends no network requests and creates no real order. It lets you watch the number of attempted requests separately from the number of actions at a fictional destination.
Choose the normal scenario. Send the request once, then repeat it: two attempts and one action. Ask the task owner to identify the original confirmation and explain where a pending case would appear.
Give the intended operation a stable identity
Attach an operation reference when the team decides to perform the action. Keep that reference through retries, restarts and handoffs. A new random reference on every attempt makes an old action look new. Scope references to the relevant account and operation; one label reused across unrelated work cannot express what was authorized.
Stripe documents a concrete provider contract: repeated requests with the same idempotency key can return the saved result, while changed parameters are rejected. Its retention and execution rules matter; check the current contract for the endpoint you use.
Now choose the changed-data scenario. The first request asks for two units. The retry asks for three using the same reference. The simulator rejects that change and preserves the original action. Correcting an order needs its own explicit business decision. A second intentionally authorized order may have identical contents and still be a separate operation.
Keep a missing confirmation visibly unresolved
Choose the lost-response scenario and send once. The destination counter becomes one, but the sender has no confirmation. The simulator shows both perspectives because it controls the entire fictional exercise. A real caller would need evidence from the destination before claiming that the action happened.
Azure’s Retry pattern explains the risk of repeating a completed operation after its response is lost. It also recommends adapting retries to the failure, using suitable delays and limiting attempts. A timeout by itself does not establish that nothing changed.
Press retry. This teaching model holds the request without another action. Press verify to inspect its fictional destination record, then retry again. The confirmed result is now reusable. In a real workflow, assign unresolved cases to someone who can inspect the provider or system of record. Record the operation reference, current evidence and next check. An empty search result may still be insufficient evidence, especially when the destination has delayed visibility.
Treat an arriving notification as a separate input
Some automations begin with a webhook: a service sends a notification that something happened. Receiving that notification again does not automatically authorize another delivery, message or spreadsheet row.
Stripe’s webhook guidance distinguishes repeated delivery of an event from separate event objects that concern the same object and event type. It also warns that events can arrive out of order. These are provider-specific facts to consider when defining what your integration recognizes as a duplicate.
For the workshop rehearsal, write two fictional notification cards for the same preparation request. Ask the operator to find the existing operation before deciding what happens next. Then introduce a legitimate correction. Does the process preserve that correction, or discard it merely because the order reference has appeared before? Keep authentication, valid state changes and duplicate handling as separate checks; recognizing a familiar reference does not prove that a message is authorized.
Make the production boundary explicit
The browser model forgets everything when reset or reloaded. It runs sequentially in memory, so it cannot demonstrate recovery after a server crash or two workers acting together. A successful demonstration is an explanation of behavior, not evidence that a live integration has those guarantees.
For production, require durable operation records and an atomic, unique reservation before competing workers claim the same operation. A separate read followed by an insert leaves a race. AWS’s discussion of idempotent APIs explains why recording the token and the associated mutations need an atomic boundary where the service controls those changes.
An external action can still succeed before your local confirmation is saved. Use the provider’s supported idempotency mechanism where available, and reconcile ambiguous outcomes against its records. A local reservation cannot make an unrelated service part of your transaction. Ask the implementer to show what happens at that boundary, how long references remain useful and who owns cases that cannot be resolved automatically.
Test the awkward cases before widening the workflow
Download the bilingual CSV beside the simulator. Its interactive cases have explicit expected counters. The production-review rows describe checks that this browser cannot perform.
Run all three exercises with the task owner. Have them predict the result before clicking. Record disagreements as requirements to resolve. Deciding whether a correction replaces an earlier request belongs to the business process; the retry mechanism should not invent that policy.
Before a live pilot, rehearse interrupted processing, unavailable evidence and simultaneous workers in an isolated test environment. Compare attempted requests, confirmed operations and unresolved cases. Avoid placing full customer messages or credentials in a troubleshooting log. Give pending work an owner and a review time. Expand only when the team can explain an unexpected result, find its evidence and recover without blindly repeating the action.
Bring the question to your team.
Three questions to explore together. Open one and use it to start a conversation.
01Which action in your workflow would be most costly to repeat, and where could you verify its result?
Write down a specific situation, listen to another perspective and agree on a small next step. If you would like an outside perspective, we can talk it through.
Discuss with the studio02Who can decide whether an uncertain operation should wait, be corrected or be attempted again?
Write down a specific situation, listen to another perspective and agree on a small next step. If you would like an outside perspective, we can talk it through.
Discuss with the studio03What test would demonstrate recovery after the destination succeeds but your confirmation is lost?
Write down a specific situation, listen to another perspective and agree on a small next step. If you would like an outside perspective, we can talk it through.
Discuss with the studioFurther reading
Public references that explore these ideas further.
What could this look like in your business?
Start with a free 30-minute conversation about your goals and priorities.
Tell us your idea
Guide + tool