Idempotency
Idempotency is the guarantee that running the same trigger event twice does not produce double side effects (don't send the email twice, don't create the CRM contact twice).
How the engine provides it
Every execution carries an idempotency_key. The key is computed at trigger time from the trigger payload — for a WooCommerce order trigger it is the order ID + status; for an incoming webhook it is a hash of the request body; for a schedule trigger it is the scheduled run timestamp.
Before the engine starts an execution it acquires a row-level lock on (workflow_id, idempotency_key) in wp_pfw_idempotency. If a row already exists with a non-failed status, the new execution short-circuits and returns the existing execution's result.
In practice this means:
- WooCommerce firing the same
order_status_completedhook twice (which can happen when third-party plugins fight) only triggers the workflow once. - A webhook caller retrying because they didn't get a 200 back will not double-trigger the workflow — the retry hits the cached result and gets the original 200.
When idempotency does NOT apply
- Manual runs — every press of Run now is intentional, so the engine assigns a unique key per run.
- Failed executions — when an execution failed, a retry with the same payload DOES re-run. We assume you want to retry after a failure.
- Cancelled executions — same; cancellation does not lock the key.
Custom idempotency keys
For trigger types where the default key doesn't match what you want (e.g. you want to allow re-running the same form submission), set idempotency: false on the trigger node's config. Use with care — you are opting out of double-fire protection.