August 5, 2026 · 5 min read

Self-hosting n8n in production: what actually breaks

The four things that take down a self-hosted n8n instance — the default database, memory on large payloads, unbounded execution history, and backups nobody has ever restored — plus the fixes that stick.

Shoaib
0 views

Self-hosting n8n starts beautifully. One `docker run`, a reverse proxy, a domain, and twenty minutes later you have a workflow automation platform that costs five dollars a month and belongs entirely to you.

The honeymoon usually lasts until the first workflow that matters runs on it. What follows is the list of things that break, roughly in the order teams hit them, and what actually fixes each one.

1. The default database is SQLite, and you will outgrow it

Out of the box, n8n stores everything in a SQLite file. This is a sensible default for trying it out and a bad one for anything you depend on. SQLite serialises writes, so a busy instance starts locking. Worse, that file is the single thing standing between you and losing every workflow you have written.

The fix is Postgres, and it is much easier before you have data. Set `DB_TYPE=postgresdb` and the connection variables, and run Postgres as a second container.

Do this on day one, even for a hobby instance. Migrating SQLite to Postgres later is a genuinely irritating afternoon involving an export, a schema mismatch and a certain amount of swearing. Doing it first costs about six lines of `docker-compose.yml`.

2. Memory, and the workflow that processes a large file

The most common outage is not dramatic. The container simply disappears and comes back, and the execution that was running is gone.

That is the OOM killer. n8n holds items in memory as they move between nodes, so a node that returns ten thousand rows, or a binary node that loads a 200MB PDF, can spike memory far beyond what the instance normally uses. On a 1GB VPS this is not a large spike.

Three things help, in order of effort:

  • Give Node.js a ceiling it can respect: set `NODE_OPTIONS=--max-old-space-size=` to something a little below your container limit, so V8 runs garbage collection hard instead of the kernel killing the process.
  • Do not pull the whole dataset into the canvas. Use pagination, use `SPLIT IN BATCHES`, and filter in the query rather than in a downstream node. Most memory problems are really "I selected everything and then filtered" problems.
  • Write binaries to disk, not through nodes. Configure the filesystem binary data mode so large files land on a volume instead of being carried between nodes in memory.

3. Execution history grows until the disk is full

n8n saves every execution — inputs, outputs, the lot. It is superb for debugging and it is unbounded by default.

A workflow running every minute produces about 43,000 executions a month. With real payloads attached, this fills a modest disk in weeks, and the failure mode is the whole instance stopping rather than anything helpfully labelled.

Set a pruning policy on the first day: turn `EXECUTIONS_DATA_PRUNE` on, keep a sensible window such as a week or two, and consider saving only failed executions for your high-frequency workflows. You almost never open a successful execution from nine days ago.

4. The backup nobody has restored

If you have done the above, your entire instance is a Postgres database plus an encryption key. The key lives at `~/.n8n/config` and it is what your stored credentials are encrypted with.

A database backup without that key is not a backup. You will restore it, watch every credential fail to decrypt, and re-enter forty OAuth connections by hand.

Back up both. Then — and this is the part everyone skips — restore into a scratch container once, and confirm a workflow with real credentials runs. A backup you have never restored is a belief, not a backup.

When to move to queue mode

Queue mode splits n8n into a main process and separate worker processes coordinated through Redis. It is the answer to "executions are queuing up behind each other" and it is not the answer to anything else.

Move to it when concurrent executions genuinely overlap and you can see them waiting — not because it sounds more production-grade. It adds Redis, at least two more containers, and a meaningfully harder debugging story. A single instance with Postgres handles far more than most teams assume.

The maintenance budget

The honest cost of self-hosting is not the five dollar server. It is roughly two hours a month: upgrades and their occasional breaking changes, certificate renewals, disk checks, and the twenty minutes where something worked yesterday and does not today.

That is a fine trade if you have someone technical and data that should not leave your infrastructure. It is a bad trade if you are self-hosting to save forty dollars a month. Do the arithmetic honestly — two hours of anyone's time is worth more than the subscription you are avoiding.

The setup that survives

  • Postgres from day one, never SQLite
  • A memory ceiling set below the container limit
  • Execution pruning on, with a window measured in days
  • Backups of the database and the encryption key, restored once to prove it
  • A reverse proxy handling TLS, with the webhook URL set correctly so callbacks resolve
  • Basic uptime monitoring, because a container that dies quietly is the whole problem

None of this is exotic, and all of it is much cheaper to do before you need it.

Where to go next

If you would rather not own any of the above, that is an entirely reasonable conclusion — n8n Hosting lists managed options and one-click deployments that take the maintenance budget off your hands.

If you are staying self-hosted, n8n Nodes has the community nodes worth knowing about, n8n Templates has workflows you can import and adapt, and the wider n8n category covers the monitoring and tooling that makes a self-hosted instance less of a mystery.

Running something in this space? Submit it — hosting, nodes and monitoring tools are exactly what people arrive here looking for.


Built something worth listing? Submit it to the directory — tools, n8n workflows and community nodes all welcome.

Keep reading