BV
All articles

n8n Execution Data Cleanup

n8n execution data grows indefinitely unless you turn on pruning. Here is how the built-in retention settings work and what to configure on a production instance.

Muhammad Bilal
Muhammad Bilal Virk
7 min read
n8n Execution Data Cleanup

n8n Execution Data Cleanup

A self-hosted n8n instance looks healthy for the first few weeks. Then, quietly, the database starts growing. Every workflow run, every webhook, every retry gets saved by default, JSON payloads and all, and nobody notices until Postgres or SQLite is eating disk space at a rate that does not match how much automation actually changed. Execution data cleanup is how you keep that from becoming an incident.

I check this setting on every self-hosted n8n instance I take over from a client, because it is disabled by default and almost nobody turns it on until the database has already grown uncomfortably large. This post covers what n8n actually stores, how the built-in pruning system works, and the settings I use to keep a production instance lean without losing the executions you actually need for debugging.


Why n8n Execution Data Grows

By default, n8n saves data for every workflow execution: the input and output of every node, error details when something fails, and any binary data the workflow touched. None of this is deleted automatically unless you configure it to be. A workflow that runs a handful of times a day accumulates slowly. A workflow triggered by a busy webhook, a voice agent's call events or a high-traffic form, can accumulate thousands of rows a week without anyone touching a single setting.


What n8n Stores

Each execution record includes the full data passed between nodes, not just a summary. For workflows handling meaningful payloads, transcripts, API responses, file references, that adds up fast per execution, not just in row count but in actual data size. If your workflow processes binary data (images, PDFs, audio), that gets stored too, tied to the execution's lifecycle.

You can control what gets saved in the first place rather than only cleaning up after the fact. Settings like saving only executions that end in an error, rather than every successful run, cut volume dramatically for high-frequency workflows where a successful run rarely needs to be reviewed later.


Execution Pruning

n8n has built-in pruning that runs automatically once enabled, controlled by the EXECUTIONS_DATA_PRUNE environment variable. With it set to true, n8n deletes finished executions once they cross an age threshold or a total count threshold, whichever comes first. It is off by default, which is exactly why so many self-hosted instances quietly grow until someone notices the disk filling up.

A few executions are never eligible for pruning regardless of age: anything still in a new, running, or waiting state, and anything you have annotated with a tag or rating. There is also a safety buffer, a short window after an execution finishes before it becomes eligible for deletion at all, so data you are actively debugging does not disappear out from under you mid-investigation.


Maximum Execution Age

EXECUTIONS_DATA_MAX_AGE sets how many hours a finished execution is kept before it qualifies for deletion, measured from when it finished, not when it started. The default is 336 hours, fourteen days. For most production setups, two to four weeks is a reasonable window, enough time to catch and debug an issue a client reports a few days late, without keeping months of execution history you will never look at again.


Maximum Execution Count

EXECUTIONS_DATA_PRUNE_MAX_COUNT caps the total number of stored executions independent of age, with a default of 10,000. Once you cross that count, n8n deletes the oldest executions first regardless of how recent your age threshold would otherwise have allowed them to stay. Both settings apply together, whichever threshold is hit first triggers the deletion. If you run a workflow at very high frequency, the count threshold will often bind before the age threshold ever does.


Database Storage

For SQLite specifically, pruned data does not free disk space automatically. The space gets reused for future execution data internally rather than returned to the operating system. If you need the disk space back, configure DB_SQLITE_VACUUM_ON_STARTUP or run a manual VACUUM operation. This is one of several reasons I move any instance handling real production volume onto Postgres early, covered in n8n Self-Hosted Setup Guide, rather than leaving it on SQLite and managing vacuum operations manually as volume grows.


Binary Data

Binary data pruning is tied to the same cycle as execution data. When an execution is hard-deleted, any binary data attached to it (files, images, audio) is removed alongside it. If you are storing binary data externally, such as S3, be aware that some enterprise-tier storage configurations do not issue a delete for every object during the standard pruning job, which is worth checking directly against current documentation if you are relying on binary storage to stay in sync with execution pruning automatically.


Monitoring Disk Usage

Do not wait for a full disk to discover pruning was never enabled. Check your database size periodically, and if you are running queue mode with heavy webhook traffic, the same volume that can back up a queue, covered in n8n Queue Mode, is exactly the volume that fills execution storage fastest. Both problems tend to show up together on the same busy instance.


Safe Production Settings

A reasonable starting point for most production instances: enable pruning, set the age threshold to somewhere between two and four weeks depending on how quickly issues typically get reported to you, and set the count threshold high enough that it rarely binds before the age threshold does, unless you are running very high frequency workflows where count is the more meaningful limit. Combine this with saving only error executions for any workflow that runs successfully at high volume and rarely needs its successful runs reviewed later, which cuts the volume being stored in the first place rather than just cleaning it up after.

For workflows tied to webhooks from Retell AI, GoHighLevel, or any high-traffic source, this matters more than it does for a workflow that runs a handful of times a day. n8n Webhook Tutorial covers the trigger side of that traffic, and getting the retention settings right from the start avoids having to do an emergency cleanup once the database has already grown large.


If your self-hosted n8n database has grown out of control, or you want pruning and retention configured correctly from the start on a new instance, that is exactly the kind of infrastructure work I take on for clients. Book a free 30-minute call and bring your current database size and workflow volume, and we can get retention set up properly.


Frequently Asked Questions

How do I delete old n8n executions?

Enable automatic pruning with the EXECUTIONS_DATA_PRUNE environment variable set to true, then configure EXECUTIONS_DATA_MAX_AGE and EXECUTIONS_DATA_PRUNE_MAX_COUNT to control how far back and how many executions are kept.

How much execution data does n8n keep?

By default, with pruning disabled, indefinitely. With pruning enabled, the default age threshold is 336 hours (fourteen days) and the default count threshold is 10,000 executions, whichever is hit first.

Why is my n8n database getting so large?

Pruning is disabled by default, so every execution's full input and output data accumulates indefinitely unless you turn it on. High-frequency workflows, especially those handling webhooks or binary data, grow the database fastest.

How do I enable n8n execution pruning?

Set EXECUTIONS_DATA_PRUNE=true along with EXECUTIONS_DATA_MAX_AGE and EXECUTIONS_DATA_PRUNE_MAX_COUNT as environment variables on your n8n instance, then restart it for the settings to take effect.

Can I keep failed executions but delete successful ones?

Yes. Configure execution saving settings to only save executions that end in an error, which cuts stored volume significantly for workflows that run successfully most of the time and rarely need those successful runs reviewed later.

Does pruning free disk space in SQLite?

Not automatically. Pruned data's disk space gets reused internally for future execution data rather than returned to the operating system. To reclaim it, configure DB_SQLITE_VACUUM_ON_STARTUP or run a manual VACUUM operation.

What executions are never pruned?

Any execution still in a new, running, or waiting state, and any execution you have annotated with a tag or rating, regardless of how old it is or how high the count threshold has climbed.


If you would rather have this configured than configure it yourself, I take on n8n self-hosted infrastructure work through Fiverr.

Muhammad Bilal
Muhammad Bilal Virk
AI automation engineer — building agents, workflows, and RPA that remove repetitive work.
Share
Newsletter

One email, when I ship something worth reading.

No cadence, no filler. Unsubscribe any time.

Free consultation

Want this built against your real numbers?

A 30-minute call to scope the workflow, agent, or automation you actually need.

Book a free consultation
Next step

Have a workflow that's burning hours every week?

Bring me one real bottleneck. I'll tell you whether it's worth automating, and what it would take.

Book 30 Minutes Call