The Scheduled Workflow That Ran Twice: Overlapping Runs in n8n
Description and use
In n8n, a scheduled hourly workflow can run concurrently if the previous run is still active, causing duplicate processing. The solution is an atomic Postgres lock with an expiring lease, ensuring only one run executes at a time and skipped runs are logged.
Problem
A scheduled n8n workflow ran twice concurrently, causing duplicate updates and duplicate emails.
Outcome
The lock mechanism prevented overlapping runs, eliminated duplicate updates, and provided transparent alerts for skipped or reclaimed executions.
Workflow
- 1. Acquire lock atomically in Postgres; if locked, skip run with alert.
- 2. If lock acquired, proceed with data pull, LLM enrichment, and write.
- 3. Release lock at end only if token matches, in always‑run path.
- 4. Log outcomes: acquired, already locked, stale lease reclaimed.
Evidence
The schedule is a clock, not a queue. It will happily start run N+1 while run N is still running.
Acquiring the lock is a single atomic statement: update the row only if it is unlocked, or if its lease has expired.
The release belongs in the workflow's always‑run path, the same place error handling lives, so a failed run frees the lock immediately and the next scheduled run can proceed on time.
- Record date: 2026-11-02T03:43:45.093Z