Skip to main content

A Successful Retry Can Still Create Duplicate Work

by Vilcorp, Staff Writer

One work order passing through a cyan retry loop and emerging as three duplicate task cards

One request, two people doing the work

Imagine a distributor submitting a quote request through a manufacturer’s website. The integration creates the CRM record and an estimating task. Its response is lost on the way back, so the sender tries again.

The second attempt succeeds too. Now two estimators have the same request, sales sees two opportunities, and the distributor may receive conflicting follow-up. The delivery dashboard is green.

This is a release problem worth catching while the workflow is still small. A webhook is a system notifying another system that something happened. Receiving that notification twice should not automatically mean doing the business work twice.

For manufacturing teams connecting quote and distributor workflows, the consequences reach beyond database cleanup. Duplicate work consumes estimating capacity and makes ownership harder to trust. Reliable systems integration needs an explicit answer to what happens when the same request returns.

Define what counts as the same request

Start with the business action: create one estimating task for this submitted quote revision.

That definition distinguishes three things that can otherwise look identical:

  • A repeated delivery: the sender delivers the same event again.
  • A second event about the same action: another notification arrives, but the estimating task already exists.
  • New business intent: the distributor submits a revised specification that legitimately needs another review.

An email address or a matching payload is not enough to make that distinction. Two valid requests can contain identical details. AWS describes why an explicit request identifier makes retries safer: it lets the caller identify the intended operation across attempts instead of asking the receiver to infer intent from similar inputs.

In the quote example, keep the source event identifier for delivery tracking and a separate business key such as customer account, quote request, revision, and action. Reuse that business key when retrying the action. Give a genuinely new revision its own identity. If the same key arrives with conflicting details, stop for review rather than silently replacing the original request.

The key should travel into the receiving system when that system supports it, so operators can connect the event to the task it created.

Record progress at the point where work changes

Checking whether an event appeared in a log is useful, but a log entry alone does not control concurrent workers. Two workers can both check, find nothing, and create the same task.

The implementation needs an atomic claim on the operation, such as a unique database constraint with a defined conflict path. When the action and its completion record share a database, commit them together. AWS’s idempotent API guidance explains the importance of recording identity and mutations as one atomic operation.

External systems introduce another boundary. A local database transaction cannot, by itself, guarantee that a remote CRM write and a notification happen once together.

Where a local change must reliably trigger a message, a transactional outbox stores the change and pending message in the same database transaction. A worker then delivers the message. It still needs duplicate handling at the receiver; the outbox does not remove that requirement. AWS’s outbox pattern describes this tradeoff.

Recover the unfinished step

Suppose the CRM record exists, the estimating task exists, and the owner notification fails. Recovery should resume the notification step using its own stable action identity.

If the task-creation call timed out and nobody knows whether the task exists, the state is uncertain. Use the destination’s idempotency support or reconcile against its stored business key before creating anything again. If neither is available, give the uncertainty to an operator with the evidence needed to resolve it.

An abandoned “in progress” claim also needs a recovery path. Define how a worker’s expired ownership is detected and how the next worker checks downstream results before resuming. Otherwise duplicate prevention can become a place where valid work gets stuck.

Make replay a reviewable operating action

After an outage, “retry everything” is a tempting button. The person pressing it should be able to see what will happen.

For the quote workflow, a useful replay view shows the original request, revision, completed steps, destination record IDs, remaining action, and reason the work stopped. Access should follow the team’s operating roles, with a record of who requested the replay.

Decide how long the system remembers completed action identities. The window needs to cover the provider’s documented retries and the manual recovery period the business allows. Once that window expires, old events should require reconciliation instead of silently becoming new work.

Provider behavior matters here. Stripe documents that manual redelivery can overlap automatic retries and events can arrive out of order. Check the equivalent guarantees for each system you connect. A replay button does not necessarily cancel the sender’s next attempt.

For a revised quote, also verify the current revision before applying an older event. Suppressing a repeated event and preventing an outdated update are separate responsibilities.

Add failure scenarios to the release review

The next integration release should prove the business outcome under more than a clean submission.

Extend the integration health checks used during web releases with a small set of targeted scenarios:

  1. Deliver the same event twice, including two attempts at the same time. Confirm one estimating task.
  2. Lose the response after the receiving system commits. Confirm recovery finds or safely reuses the existing result.
  3. Stop after task creation but before notification. Confirm only the unfinished action resumes.
  4. Deliver a new quote revision, then replay the old event. Confirm the newer revision remains authoritative.
  5. Replay an event beyond the supported duplicate-detection window. Confirm it enters the agreed reconciliation path.

Run these checks with controlled test records and non-customer notification destinations. Inspect the receiving systems and operator queue, not only the webhook response.

The broader discipline in Treat Lead Handoffs Like Systems Integration Work still applies: follow the request until the receiving team has usable, correctly assigned work. Add one more question to that review: did the team receive it the right number of times?

Judge recovery by the work it leaves behind

Retry success rate cannot explain whether two people are now handling the same quote. Pair delivery metrics with duplicate actions prevented, uncertain outcomes awaiting review, age of unfinished work, and downstream duplicates discovered by operators.

Before shipping, agree on the request identity, the boundary that prevents duplicate actions, the way unfinished steps resume, and the limits of manual replay. Those four decisions give engineering and operations a shared definition of recovery.

A healthy retry restores progress while preserving work that already succeeded. That is the outcome the release should prove.

If your web forms, CRM, or operational tools create duplicate tasks or uncertain handoffs, Start a Project to map the request identities, recovery paths, and release checks around one critical workflow.

More articles

Bring the next system into focus.

Start a web, integration, or applied AI engagement—or route an active support need to the right channel.