Skip to content

Idempotency

Idempotency is a property of an action where repeating the same request does not add an intended effect beyond the first execution. In automation, it is used to prevent a retry from creating the same business action again.

Source content checked . English translation published 2026-10-27.

In business automation

Idempotency matters when the same action might be sent again after a failure or duplicate event. The goal is for a retry not to create an additional business outcome for the same request. A stable identifier helps link attempts, but protection also requires a way to store the action's state and prevent two attempts from being accepted concurrently as new actions.

An event ID is not a customer ID

A customer can submit two different inquiries, and both can be valid. Their email address can help locate the customer record, but does not prove the inquiries are the same event. By contrast, two deliveries of the same source message can request the exact same business action again.

Before choosing a key, define what counts as the same action: a particular source event, in a particular system, requesting a particular outcome. If the source provides a stable event ID, store it with its context. When retrying the same action, do not generate a new key just because the previous run did not return a response.

Idempotency describes the intended effect, and does not require an identical HTTP response every time. For example, an action that removes an item can leave it absent even if the response to the repeated request differs from the first response.

Why search then create can produce duplicates

Suppose two processes handle the same event. The first searches for a record and does not find one. Before it can create the record, the second also searches and finds nothing. Both proceed to create it. The search worked in each run, but did not prevent a duplicate across runs.

Enforcing a uniqueness rule requires appropriate protection in the destination. PostgreSQL documents an atomic insert-or-update outcome with ON CONFLICT DO UPDATE, as long as no separate error prevents the operation. This protects a particular database statement, not every business process that uses it, and does not guarantee that the process is idempotent.

Even an atomic update can add another cumulative value or trigger a related action again. Choose a key and a conflict-handling rule that fit the intended action. A marker that someone started handling an event does not prove that handling is complete. A competing attempt should wait according to a defined policy or check the current state.

What to do when the outcome is unknown

A timeout does not mean the other system did not perform the request. First, check the destination using a stable source ID, a saved record ID, or a status lookup supported by the provider. If a completed execution is found, use the existing result instead of creating a new action.

If the provider allows retries, use the same key only while the provider's documented protection remains valid. If the outcome cannot be determined or the key is no longer protected, leave the state as unknown and send it for reconciliation or review by the process owner. A new key is not an automatic solution to uncertainty.

The rules also depend on the API version. Stripe documents that API v1 saves the first response after execution begins, including certain error responses, while API v2 has different retry behavior. So do not assume that every error will be resolved by continuing to send the same request.

Where database protection ends

Creating a record and sending a message are two different effects. If the record is created but the message fails, rerunning the entire process may repeat a step that already succeeded. Store the intent, known state, and result of related actions separately.

An atomic database operation alone does not make an email or external service call part of the same transaction. If the external service does not provide a suitable way to prevent duplicates or determine an outcome, document the limitation and the manual handling path. The checklist table here is a planning and acceptance template, not proof that any provider connection has been activated and tested.

Scroll the table sideways to read every column.

Retry test table: illustrative examples, not a connection that was activated and tested
ScenarioStable event keyExpected actionEvidence to collect
The same event arrives againevent-demo-AUse the result confirmed as completed; do not create a new business effect.Original and repeated record IDs, and the number of business actions actually performed.
Two attempts run concurrentlyevent-demo-AEnforce acceptance of one action; the other attempt waits according to policy or is sent for review. An in-progress status does not mean the action is complete.Action acceptance decision, run statuses, and final record ID.
Same key with different contentevent-demo-AReject the conflict or require review; do not silently return a result for different instructions.Conflict outcome and a limited content comparison, without unnecessary personal data.
Stable key is missingmissingReject or send for review; do not create a new action key on every retry.Validation result and evidence that no new write was accepted.
Timeout after writing to an external serviceevent-demo-AFirst check using the stable ID. Retry with the same provider key only while the documented protection is valid; otherwise investigate the state.Destination status or saved result; an unresolved outcome remains unknown.
Restart or delayed retryevent-demo-ARestore persistent state, check key retention, and reconcile related actions separately.Saved action state and a check of the destination outcome after restart.
Download the retry test table (CSV)

Examples

These examples illustrate a possible workflow. Adapt the connections and rules to your own systems.

The same order arrives again

As an illustrative example, a process creates a shipping task using the order ID and action purpose as a unique key. If no response is received and the event is delivered again, it checks whether the task already exists and its status before deciding whether to continue. The customer ID alone does not identify the order.

  1. Define which event and action the key represents.
  2. Store the action key and state in persistent storage.
  3. Check whether a task was created at the destination and retrieve its ID.
  4. Use the completed result or leave the case for investigation, without blindly creating a new key.

The desired acceptance result is one shipping task for the same action, with evidence in the destination. This is an expectation to verify, not a test result obtained here.

The record was created, but the message status is unknown

In another example, a support inquiry was recorded in the CRM, but an internal update remains in an unknown state. Do not restart the inquiry creation. Check the record and message status separately, and define a recovery path for each related action that fits the service's capabilities.

Relevant tools

Supabase
Uniqueness constraints and persistent data can help build a duplicate-execution prevention mechanism. The design also needs to cover conflict handling and reconciliation of actions sent to external services.
n8n
An event-driven process can carry a source ID between steps, but simply using the platform does not guarantee that the destination enforces the intended uniqueness rule.

What to check

  • Preventing duplicates in temporary memory is not enough after a restart. Store a stable ID, state, and execution result persistently.
  • The same key with different business content is a conflict that requires rejection or review, not silent approval to return a result that does not match the request.
  • A new key on every retry prevents the service from recognizing the same action. Do not use personal or sensitive details as a key.
  • A record marked as in progress does not confirm that the action completed. Define a bounded wait and an investigation path for stuck or unknown states.
  • Key retention periods and retry rules depend on the provider and API version. There is no single time window that applies to every service.
  • A preliminary search, a successful run, or a database uniqueness constraint does not prove that a duplicate message or external action was prevented as well.

Related terms

Sources