n8n Memory Usage Growing Over Time? Check Your Execution Data Settings

Mike Holownych
Last verified: July 28, 2026
#n8n#automation
Share:

Quick Answer

n8n’s default settings save full input/output data for every successful execution, keep manual test runs indefinitely, and prune execution history slowly. On a small VPS, that accumulates: growing execution history gets loaded into memory for the dashboard, workflow editor, and execution logs, and RAM usage climbs until the process is killed or the server becomes unresponsive. The fix is a handful of environment variables that disable success-data storage, prune aggressively, and cap manual execution retention.

Why n8n’s Defaults Aren’t Production-Tuned

n8n’s out-of-the-box configuration is built for debugging every execution in detail, which is the right default for local development and the wrong one for a small production instance:

  • executions.saveDataOnSuccess: true — saves full input/output for every successful execution, not just failures
  • executions.saveDataManualExecutions: true — manual test runs (every click of “Test Workflow”) are saved and never automatically purged
  • executions.pruneDataMaxAge: 336 — execution data is kept for two weeks before pruning

Each node in a workflow can save its own copy of the data passing through it — the trigger’s input, a transform node’s input and output, a database write’s confirmation. A workflow with several nodes processing a non-trivial payload can end up storing several copies of essentially the same data per execution. On a workflow that runs frequently, that adds up fast, and it’s memory that gets loaded back in whenever you open the execution list or workflow editor.

Five Configuration Changes

1. Disable Success Data Storage

N8N_EXECUTIONS_DATA_SAVE_ON_SUCCESS=false

You lose per-execution history for successful runs, but error logs are unaffected — errors are what you actually need for debugging in practice.

2. Limit Manual Execution Storage

N8N_EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=false
N8N_EXECUTIONS_DATA_MAX_AGE=24

Stops manual test runs from being retained indefinitely.

3. Aggressive Database Pruning

N8N_EXECUTIONS_DATA_PRUNE=true
N8N_EXECUTIONS_DATA_MAX_AGE=24
N8N_EXECUTIONS_DATA_PRUNE_MAX_COUNT=100

Caps retained execution history — adjust the numbers based on how much history you actually need for debugging versus how much headroom your instance has.

4. Execution Timeouts

N8N_EXECUTIONS_PROCESS=main
EXECUTIONS_TIMEOUT=300
EXECUTIONS_TIMEOUT_MAX=600

Puts a ceiling on how long a single execution can run, so a runaway workflow (an infinite loop, a hung HTTP call with no timeout of its own) can’t consume resources indefinitely.

5. Node.js Memory Limit

NODE_OPTIONS="--max-old-space-size=2048 --optimize-for-size"

Sets an explicit heap ceiling appropriate to your instance size rather than letting Node’s default grow unconstrained.

Common Contributors to Memory Pressure

Storing large API responses in full. If an upstream API returns a large payload and you only need a few fields from it, extract just those fields early rather than passing the full response through the rest of the workflow:

// Instead of passing the full API response through
return items[0].json;

// Extract only what's needed
return [{
  temperature: items[0].json.main.temp,
  humidity: items[0].json.main.humidity,
  timestamp: new Date().toISOString()
}];

Manual test runs accumulating in production. Every “Test Workflow” click saves execution data by default. Repeated testing against a production instance builds up entries that serve no ongoing purpose — either test against a separate instance, or set N8N_EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=false.

Large file processing without batching. Loading large files fully into memory across several concurrent executions multiplies quickly. Process files in smaller batches instead:

{
  "batchSize": 3,
  "options": {
    "reset": false
  }
}

You Don’t Need to Keep Everything

The instinct to “save all execution data, just in case” is understandable but usually the wrong trade-off for a resource-constrained instance. Error logs — which n8n retains regardless of your success-data settings — cover the debugging case that actually matters. Full execution history for successful runs is rarely revisited, and it’s the thing most likely to be quietly consuming your server’s memory.

Try It

Add these three lines to your n8n environment configuration and restart:

N8N_EXECUTIONS_DATA_SAVE_ON_SUCCESS=false
N8N_EXECUTIONS_DATA_MAX_AGE=24
N8N_EXECUTIONS_DATA_PRUNE=true

Watch memory usage over the following hour to confirm the change is having the expected effect for your specific workload — the actual reduction depends on how much data your workflows were saving before, so measure it rather than assuming a fixed percentage.

See n8n Enterprise Architecture for the broader production-readiness picture beyond memory tuning.

MH

About Mike Holownych

Building AI Syndicate—governance infrastructure for AI agents in regulated environments. 20+ years enterprise operations, now applying that reliability discipline to AI deployment.