
An n8n execution stuck in Running is almost never a workflow that is still working. In queue mode, it means the worker that was executing it died without updating the database — usually killed by the kernel for using too much memory — so the status row is frozen at running and nothing will ever change it. The Stop button does nothing because there is no live process to send a stop signal to. Restarting n8n does not resume the run, because there is no state left in memory to resume from. What you have is an orphaned database row, and the fix is to prove the worker died, clear the row, and remove the reason it died.
We run self-hosted n8n in production for our own operations and for client stacks, and stuck executions are the support ticket we get most often after credential errors. The pattern is consistent enough to be boring: someone sees an execution counting up past two hours, assumes the workflow is looping, and spends an afternoon rewriting nodes that were fine. The workflow was never the problem.
Is the execution actually running, or just labelled that way?
Open the stuck execution and look at the node data. If the last node produced output at 03:14 and it is now 09:40, with no end time recorded, nothing is executing. A live long-running workflow keeps producing node output; a zombie does not.
The three signals that tell you it is an orphan, not a slow run:
- No new node output since a fixed timestamp. Live runs advance. Orphans freeze.
- Stop does nothing. Neither the UI button nor
POST /api/v1/executions/{id}/stophas any effect, because the stop signal is routed to a process that no longer exists. - A gap in the worker logs at exactly that timestamp. Restart lines, an exit code, or simply no log output for the period the execution supposedly spent working.
Get all three and you can stop debugging the workflow entirely. This is an infrastructure failure wearing a workflow costume.
Queued and Running are different bugs with the same symptom
The most expensive mistake here is treating both statuses as one problem. They fail for opposite reasons, and the fixes do not overlap.
Stuck on Queued means the main instance wrote the job into Redis and no worker ever collected it. Nothing crashed — the job is intact and waiting. Causes, in the order we find them:
- No worker container is running at all. In queue mode the main instance only enqueues; it does not execute. A deployment that forgets the worker service looks exactly like this.
- Main and workers point at different Redis databases.
QUEUE_BULL_REDIS_DBdefaults to0, and a mismatch produces a perfectly healthy queue that nobody is reading. - Every worker slot is busy. Worker concurrency defaults to
10, and ten slow jobs will park everything behind them.
Stuck on Running means a worker did collect the job and then stopped reporting. That is a crash. Go straight to memory.
Exit code 137 is the answer most of the time
Check the worker container directly:
docker inspect <worker-container> \
--format '{{.State.OOMKilled}} {{.State.ExitCode}} {{.State.StartedAt}}'
true 137 is the kernel OOM-killer. It terminates the process instantly, with no signal handler, no error write, no database update. From n8n's perspective the execution never ended — which is precisely why the row stays on running.
This is silent by design and it is why so many teams look in the wrong place. Nothing appears in the n8n error log, because n8n never got the chance to write one. The evidence lives in the container runtime, not the application.
What actually pushes a worker over its memory ceiling, from the stacks we have debugged:
- Binary files passed through workflow items. A 40 MB PDF fetched by an HTTP node and carried through six more nodes is held in memory the whole way. Write to S3 or the filesystem and pass a reference instead.
- Unbatched database or API reads. A node that returns 200,000 items materialises 200,000 items. Batch it.
- Concurrency times payload size. A worker with
--concurrency 10and a 512 MB limit is fine until three large jobs land together. Lower concurrency per worker and add more workers instead — we go into the arithmetic in how many n8n workers you actually need. EXECUTIONS_DATA_SAVE_ON_PROGRESSleft on. It defaults tofalsefor good reason. Turning it on writes node data continuously and inflates both memory and database load.
Clearing the zombies without losing your evidence
Capture the logs first. Deleting the execution deletes the record of what it was doing when it died, and you will want that ten minutes later.
Then pick one:
- Delete from the UI. Fine for a handful. Works even though Stop does not, because deleting removes the row rather than signalling a process.
- Restart the main instance. On startup n8n runs a recovery pass over executions still marked
runningand marks the orphans as crashed. This is the cleanest bulk fix and it touches no database directly. - Update the database. Only if you have hundreds and cannot restart. Mark the rows finished or delete them in the
execution_entitytable. Take a backup first, and treat this as a last resort rather than a routine.
If you are clearing zombies more than once, stop clearing and start fixing. Recurring orphans are a memory ceiling problem, not a housekeeping problem.
The settings that stop it happening again
Four changes, in the order they pay off:
Raise the worker memory limit above your largest single execution. Not your average — your worst case. Measure the biggest payload a workflow legitimately handles and give the container headroom above it. This one change eliminates most stuck executions on the instances we inherit.
Set EXECUTIONS_TIMEOUT to a real number. It defaults to -1, which means no timeout at all, and EXECUTIONS_TIMEOUT_MAX caps what individual workflows can request at 3600 seconds. A 900-second default kills genuine runaways before they occupy a worker slot for a day. Be clear about what this buys you: a timeout is enforced by a living process, so it prevents one class of stuck run and does nothing for an execution whose process is already gone.
Tune N8N_GRACEFUL_SHUTDOWN_TIMEOUT to your longest normal job. It defaults to 30 seconds. If your workflows routinely run longer, every deploy and every container restart chops jobs mid-flight and manufactures orphans on a schedule. Raise it past your realistic maximum and planned restarts stop generating stuck rows.
Leave the stalled-job detection alone. QUEUE_WORKER_STALLED_INTERVAL defaults to 30000 ms and QUEUE_WORKER_LOCK_DURATION to 60000 ms. These control how the queue notices a worker has gone quiet, and the defaults are sensible. Worth knowing: QUEUE_WORKER_MAX_STALLED_COUNT was removed in n8n 2.0 and setting it now has no effect, so if you copied a 2024 tuning guide, that line in your compose file is dead weight. The full list is in the n8n queue mode environment variables reference.
Alert on duration, not on failure
Here is the part most teams miss. A stuck execution never fails, so your error workflow never fires. Every failure-based alert in n8n is blind to this exact problem — the run does not error, it simply stops existing while the row claims otherwise.
You need a check that runs outside n8n and asks a different question: is anything still marked running past a threshold it should never cross? Query the executions API on a schedule, count anything running for longer than your timeout ceiling, and alert on the count. Pair it with a heartbeat on the workers themselves — if a worker restarts, you want to know before a client notices a missed job. We cover the surrounding setup in our guide to n8n error handling and monitoring, and if you are running AI agents on the same instance, per-run tracing gives you the same visibility at the step level — see n8n AI agent observability.
The honest summary: this problem is not a workflow bug and you cannot fix it inside the canvas. It is a container that ran out of memory, a queue with nobody listening, or a restart that did not wait. Once you look in the right place it takes about ten minutes.
Get a free automation audit
If you are clearing stuck executions by hand every week, something upstream is wrong and it is costing you more than the cleanup. We review self-hosted n8n instances for exactly this class of problem — worker sizing, memory ceilings, queue configuration, and the monitoring gap that lets silent failures run for days. Get a free automation audit and we will tell you what is actually breaking, whether or not you work with us afterwards.
