n8n Execution Logs: Read, Retain & Debug Executions
n8n execution logs record what each node received, returned, and how long it took on every run. Here is how to read them to debug a bad execution, control retention with the pruning env vars, and why teams ship logs to an external store.
n8n execution logs show a per-node record of every run: each node's input and output data, its status (success or error), and its duration, plus whether the whole execution finished, failed, or is still running. What they do not show is cost, patterns across many runs, or why a scheduled run never started. This guide covers how to read an execution to debug it, how to control retention with n8n's pruning settings, and why teams send logs to an external store for history and cross-run analysis.
What the n8n execution log actually shows
Open Executions in the n8n editor and you get a list of runs with a status, a start time, and a duration. Click into one and the canvas replays that specific execution: every node is marked success or error, and you can open any node to see the exact items that went in and the exact items that came out. That input/output pairing is the single most useful thing in the log, because most workflow bugs are really data-shape bugs, and seeing the item a node received tells you why it did what it did.
The log also records mode (manual, trigger, webhook, or scheduled), the total run time, and, on a failure, which node threw and the error message it raised. For a single misbehaving run, that is usually enough to find the problem.
What the execution log does not tell you
The log is scoped to one run at a time, and it only records runs that actually started. That leaves several common questions unanswered, and knowing which is which saves you from staring at a log that was never going to have the answer:
| Question | Answerable from the execution log? | What you need instead |
|---|---|---|
| Why did node X error on this run? | Yes — open the node, read its input, output, and error | Nothing else |
| What did this LLM node cost? | No — duration only, never tokens or dollars | Capture token usage per call and price it (see n8n cost tracking) |
| Is this error new, or has it happened 40 times this week? | No — one run at a time, no aggregation | Cross-run analysis over a retained log store |
| Why did my scheduled run not happen at all? | No — a run that never started leaves no execution record | Trigger/heartbeat monitoring outside n8n |
| What did the same workflow look like last month? | Only if it survived pruning | External retention (logs shipped off the instance) |
How to read a bad execution and pin data
Start at the node marked with the error and read its input first, not its output. The error message tells you what broke, but the input tells you why: a missing field, an empty array, a string where a number was expected, an item count of zero. Walk backwards node by node until the input looks wrong, and the node just before that is usually where the real problem is.
To debug faster, use pinned data. In the editor you can pin the output of a trigger or an earlier node so that re-running the workflow reuses that exact data instead of fetching live. That lets you reproduce a specific failing payload over and over while you fix a downstream node, without hammering an external API or waiting for a new trigger. Combined with the execution list's option to copy an item's JSON, you can lift the exact failing payload out of a past run and pin it into a fresh debugging session.
When a failure is intermittent rather than reproducible, the single-run log stops being enough. That is the point where you want to see the pattern across runs, which is covered in the guide to debugging silent failures in n8n workflows: debug silent failures.
Execution data retention and pruning
By default n8n keeps execution data, and on a busy instance that data grows fast, because every run stores the full input and output of every node. Left unbounded it bloats the database and slows the Executions view. n8n controls this with pruning: set EXECUTIONS_DATA_PRUNE to true to enable automatic deletion, EXECUTIONS_DATA_MAX_AGE to the number of hours to keep executions before they are removed, and EXECUTIONS_DATA_PRUNE_MAX_COUNT to cap the total number of executions retained regardless of age.
The tradeoff is direct: pruning is what keeps your instance healthy, and pruning is also what destroys your history. Set MAX_AGE to 336 (14 days) and any error older than two weeks is simply gone, along with the input data you would need to understand it. So the retention window you can afford on the n8n database is almost always shorter than the window you actually want for debugging and trend analysis. Turning pruning off is not the answer either, because then the database is the thing that eventually falls over.
There is also a distinction worth knowing: n8n can save full execution data for every run, or only for failed runs, or none. Saving everything gives you the richest log but the fastest growth, which pushes you back toward aggressive pruning and the history you lose with it.
Why teams ship logs to an external store
The way out of the pruning tradeoff is to stop treating the n8n database as your log store. Prune the instance aggressively to keep it fast, and send a compact record of each execution somewhere built to retain it. Once execution data lives in an external store, you keep months of history without bloating n8n, and you unlock the cross-run questions the built-in log can never answer: is this error rate climbing, which workflow fails most often, did last night's deploy change anything.
That is what an observability layer does. Obsivara connects to n8n read-only and ingests execution data as it happens, so your instance can prune freely while the history and the cross-run analysis live outside it. There is no logging node to maintain inside every workflow and no proxy in your request path. See how to wire it up in the complete monitoring guide, How to monitor n8n workflows, and the native connector at /connect/n8n. If you would rather see it against your real executions first, a free 48-hour audit is at /free-audit.
Frequently asked questions
Where are n8n execution logs stored?
In n8n's own database — the same Postgres or SQLite instance the editor runs on. Each execution stores its status, timing, and the full input and output of every node, which is why the data grows quickly and why n8n has pruning settings to keep it bounded. The editor's Executions view reads from that same database.
How long does n8n keep execution data?
It depends on your pruning configuration. With EXECUTIONS_DATA_PRUNE enabled, executions are deleted once they exceed EXECUTIONS_DATA_MAX_AGE (in hours) or once the total count passes EXECUTIONS_DATA_PRUNE_MAX_COUNT, whichever comes first. With pruning off, data is kept indefinitely, which eventually bloats the database — so most teams set a window and accept that older history is gone.
How do I stop n8n execution logs from filling my database?
Enable pruning with EXECUTIONS_DATA_PRUNE=true and set a MAX_AGE and/or MAX_COUNT that keeps the instance fast. You can also choose to save execution data only for failed runs rather than all runs. The catch is that anything pruned is unrecoverable, so if you need longer history for debugging or trends, ship execution data to an external store and prune the instance itself aggressively.
Can n8n execution logs tell me why a scheduled run did not happen?
No. The execution log only records runs that actually started, so a scheduled trigger that never fired — because the workflow was inactive, the instance was down, or the schedule was misconfigured — leaves no entry at all. Catching a missing run requires monitoring the trigger from outside n8n, such as a heartbeat or an alert on expected-but-absent executions.
See your AI operations clearly.
Connect your stack in minutes — Obsivara discovers every workflow, scores its health, and attributes every dollar.