Prevent duplicate n8n webhook executions without pretending delivery happens exactly once.
Webhook providers can retry. Operators can retry. Network timeouts can happen after the destination already accepted a write. The production goal is therefore not “this workflow executes once.” The goal is: the same logical event can be processed again without creating a second business action.
The failure you are trying to prevent
Imagine a webhook that creates a CRM record and then returns a response. The CRM accepts the create request, but the response is lost. The webhook sender sees a timeout and retries. If the workflow treats the retry as new work, you now have two CRM records — even though neither system behaved unusually.
The same pattern can duplicate orders, emails, tickets, invoices, Slack messages, database rows and any other state-changing action.
Normalize → validate → reserve → act → complete
The important word is atomically. A separate “look up ID, then insert ID” sequence can race when two copies arrive at nearly the same time. A uniqueness constraint or another atomic claim mechanism lets only one execution win.
1. Pick the right idempotency key
Prefer a stable identifier generated by the source event: webhook event ID, order event ID, message ID or another value that represents the specific logical event. Do not deduplicate only by customer name, amount or a loose timestamp — two legitimate events can share those values.
Normalize the key before you use it and reject missing or malformed keys when duplicate side effects would be costly.
2. Reserve before the side effect
A database unique constraint is a common pattern because it turns the duplicate decision into one atomic operation.
Continue to the business action only when the insert returns a row. If it returns nothing, another execution already owns or completed that logical event.
3. Do not confuse “reserved” with “completed”
There is another failure gap: the event can be reserved and then the downstream action can fail. If every future replay is discarded forever, a transient failure becomes permanent data loss.
Track state such as processing → completed and define what makes a failed/stale reservation retryable. The right recovery rule depends on the downstream action and whether it supports its own idempotency key.
4. Test the paths that demos usually skip
One reservation succeeds and exactly one business action occurs.
Second copy creates no additional side effect.
Two copies arrive together; only one atomic reservation wins.
Workflow rejects or quarantines instead of inventing a new key.
Webhook retry does not duplicate the destination write.
Failure is visible and your recovery policy can retry safely.
Operator can replay a failed event without bypassing duplicate protection.
5. Keep the webhook response and business outcome separate
Responding quickly can reduce unnecessary sender retries, but it does not replace failure handling. If you acknowledge before the full business process finishes, downstream failures must be independently observable, recoverable and owned by someone.
n8n provides separate test and production webhook URLs; make endpoint selection part of the release gate rather than relying on memory.
Check whether duplicate/retry risks are obvious in your export.
The browser-based scanner looks for webhook + side-effect combinations, retry settings, continue-on-error patterns, error workflow signals, test endpoints and several handoff risks. It never uploads the JSON.
Get a workflow-specific second pass.
The fixed $250 review takes one exported n8n workflow plus expected behavior and synthetic/redacted examples, then returns severity-ranked findings and regression cases within 48 hours after materials arrive.
See the independent QA pilot