HostCloud logo
Automation & DevOps

Self-hosting n8n on a VPS: the setup guide that covers what breaks

Self-hosting n8n on a VPS removes per-execution pricing but adds ops work most guides skip. The real specs, the Docker setup, the encryption key trap, and when queue mode becomes necessary.

V Vinod Kulkarni
2 August 2026 · 11 min read
Self-hosting n8n on a VPS: the setup guide that covers what breaks

Self-hosting n8n on a VPS: the setup guide that covers what breaks

TL;DR: n8n Cloud charges per execution. A self-hosted n8n instance on a VPS costs the same whether it runs a hundred workflow executions a month or a hundred thousand, which is why teams move once their automation volume becomes real. The Community Edition is free to self-host for internal business purposes under n8n's Sustainable Use License.

What most setup guides skip is everything after docker compose up. The encryption key that makes every stored credential unreadable if you lose it. The SQLite default that will corrupt under concurrent load. The webhook URL misconfiguration that silently breaks every external trigger. This guide covers the install and the four things that break afterwards.

Why teams self-host n8n

n8n is a workflow automation tool in the same category as Zapier and Make, with one structural difference: you can run it on your own server. That single difference changes the cost curve completely.

Hosted automation platforms price by execution or by task. Every time a workflow runs a step, the meter moves. That model is fine when you are automating a form notification a few dozen times a month. It stops being fine the moment you build something that polls an API every five minutes, or processes a webhook for every order in a store doing decent volume.

A workflow running every five minutes fires roughly 8,640 times a month. Multiply that by the number of nodes in the workflow and you are into five or six figures of billable operations from a single automation.

On a self-hosted instance, that same workflow costs whatever your VPS costs. The number does not move.

The second reason is data. Self-hosting means customer records, API keys and internal documents pass through infrastructure you control rather than a third party's multi-tenant platform. For anyone thinking about vendor sprawl under India's data protection regime, reducing the number of external processors that touch personal data is a genuine simplification. Our guide to DPDP Act hosting obligations covers why that vendor list matters.

The third reason is capability. Self-hosted n8n lets you run arbitrary code nodes, install community nodes, and reach services on your private network. A hosted platform will not let you query an internal database that has no public endpoint.

The trade is that you now own the operations. Uptime, updates, backups, security patching. That is not a small thing, and it is the part this guide spends most of its time on.

Architecture diagram showing a VPS containing n8n, PostgreSQL and a Caddy reverse proxy, with HTTPS traffic inbound and webhook connections outbound to external services

What the licence actually permits

n8n is fair-code, not open source in the OSI sense, and the distinction has practical consequences that catch agencies out.

The Community Edition is distributed under the Sustainable Use License. You can use it for free, internally, for your own business purposes. You can modify it. You can self-host it on your own infrastructure at any scale.

What you cannot do is host n8n as a service for third parties, or resell access to it, without a commercial agreement. An agency running one internal n8n instance to automate its own operations is fine. The same agency spinning up an n8n instance per client and charging for access is in different territory.

The grey area in between is common and worth thinking about before you build a business model on it. Building and maintaining workflows for a client on the client's own self-hosted instance is generally fine. Running the instance yourself and selling the client access to it is where the licence bites.

Enterprise features, SSO, log streaming, external secret stores, environment support, sit behind a paid licence regardless of hosting. Everything in this guide works on Community Edition.

Sizing the VPS honestly

Most guides tell you n8n runs on 1GB of RAM. Technically true, and misleading for anything past a demo.

The real number depends on three things: how many workflows run concurrently, whether your workflows handle large payloads, and whether you keep execution history.

1 vCPU / 2GB RAM. Sufficient for a personal instance with a handful of workflows, low concurrency, and small payloads. This will run n8n plus SQLite. It will not comfortably run n8n plus PostgreSQL plus a reverse proxy plus your execution history, and it will start swapping under any real load. Fine for learning, thin for production.

2 vCPU / 4GB RAM. The realistic production floor for a small business. Handles n8n with PostgreSQL, a reverse proxy, moderate concurrency, and normal payload sizes. Most teams running fifteen to fifty workflows sit here comfortably.

4 vCPU / 8GB RAM. Needed once you are processing large data volumes, running many workflows concurrently, or handling file transformations. Also the point at which queue mode starts making sense.

Two things drive memory consumption harder than people expect. The first is payload size, because n8n holds workflow data in memory during execution, so a workflow pulling a 50MB JSON response and passing it through five nodes has a memory footprint far larger than the file. The second is execution history, which lives in your database and grows without limit unless you prune it.

Disk is usually a non-issue at 40 to 50GB unless you retain execution data aggressively, in which case the database becomes the largest thing on the machine.

For anything serious, a VPS with guaranteed resources beats a shared plan, because n8n is a long-running process with unpredictable CPU spikes and shared hosting will throttle exactly when a workflow needs headroom. If your automations serve Indian users or call Indian APIs, an India-region server also removes 200-plus milliseconds of round trip from every external call.

Choosing your database before you install

n8n defaults to SQLite. Do not run production on it.

SQLite is a single file with a single writer. It is genuinely convenient for a local test and genuinely dangerous once multiple workflows execute concurrently, because concurrent writes produce lock contention, and lock contention under load produces corruption. A corrupted SQLite database takes every stored workflow and credential with it.

Use PostgreSQL. It is the officially supported production database, it handles concurrency properly, and switching later is a migration you will not enjoy.

Make this decision before the first install. Moving from SQLite to PostgreSQL after you have built forty workflows means exporting, reconfiguring and re-importing, and credentials do not always survive the trip cleanly.

The install, step by step

This is a Docker Compose setup on Ubuntu, with PostgreSQL and Caddy handling TLS automatically. Caddy is the shortcut here because it provisions and renews Let's Encrypt certificates without configuration.

Point your DNS first. Create an A record for n8n.yourdomain.com pointing to the VPS IP, before you start the containers. Caddy needs to resolve the hostname to issue a certificate, and starting first means watching it fail in a retry loop.

Prepare the server. Update packages, create a non-root user with sudo, install Docker and the Compose plugin, and configure the firewall to allow only ports 22, 80 and 443. Do not expose port 5678 publicly. n8n should only be reachable through the reverse proxy.

Create the environment file. In a directory such as /opt/n8n, create a .env file holding your domain, timezone, database credentials, and encryption key. Generate the encryption key with openssl rand -hex 32 and set it explicitly rather than letting n8n generate one for you. Set GENERIC_TIMEZONE=Asia/Kolkata so scheduled workflows fire when you expect, because the default is UTC and a cron set for 9am will run at 2:30pm IST otherwise.

Write the Compose file. Three services: postgres with a named volume for data, n8n depending on postgres with the database environment variables and N8N_HOST, N8N_PROTOCOL=https and WEBHOOK_URL set to your full public URL, and caddy exposing 80 and 443 with a two-line Caddyfile reverse-proxying your domain to n8n:5678. Set restart: unless-stopped on all three.

Start it. docker compose up -d, then watch docker compose logs -f n8n until the instance reports ready. Visit your domain over HTTPS and create the owner account immediately, because until you do, an unauthenticated instance is sitting on the public internet.

The whole thing takes about twenty minutes on a clean server. The next four sections cover what goes wrong afterwards.

The encryption key nobody backs up

n8n encrypts stored credentials at rest using an encryption key. If that key is lost, every credential in the instance becomes permanently unreadable.

Not recoverable. Not resettable. You re-enter every API key, OAuth token and database password by hand.

When you do not set the key explicitly, n8n generates one on first run and writes it to a config file inside the container's data directory. If your Docker volume is deleted, or you rebuild the stack on a new server without copying that volume, the key is gone and your credentials go with it.

This is the single most common way people lose a self-hosted n8n instance, and it usually happens during what should have been a routine migration.

Set N8N_ENCRYPTION_KEY explicitly in your environment file. Store a copy of that key somewhere outside the server, in a password manager, not in the same backup as the database. A backup containing both the encrypted database and the key that decrypts it offers less protection than you think.

When you migrate to a new server, move the key first and verify a credential decrypts before you decommission the old machine.

Webhook URLs and the trigger that never fires

The second most common failure is subtler, because nothing errors. The workflow simply never runs.

n8n needs to know its own public URL to construct webhook endpoints. Inside a container it cannot infer this. If WEBHOOK_URL is unset or wrong, n8n generates webhook URLs pointing at localhost:5678, and the external service you registered them with cannot reach that address.

You register the webhook. The service accepts it. Nothing ever arrives.

Set WEBHOOK_URL=https://n8n.yourdomain.com/ including the protocol and trailing slash, alongside N8N_HOST and N8N_PROTOCOL=https. Then verify: open a workflow with a webhook trigger and check that the production URL displayed in the node uses your real domain.

Two related traps. Test webhook URLs only listen while the editor is open in test mode, so an integration that works during testing and dies afterwards usually means the test URL was registered instead of the production one. And if your reverse proxy strips or rewrites paths, webhook routing breaks in ways that look like n8n bugs, which is why the two-line Caddy config above passes everything through untouched.

Symptom Likely cause Fix
Webhook registered but never fires WEBHOOK_URL unset or wrong Set full public URL with protocol
Works in editor, dies after closing Test URL registered instead of production Re-register with the production URL
Credentials unreadable after migration Encryption key not carried over Restore original N8N_ENCRYPTION_KEY
Random execution failures under load SQLite lock contention Migrate to PostgreSQL
Scheduled workflows run at wrong time Timezone defaulting to UTC Set GENERIC_TIMEZONE=Asia/Kolkata
Instance slows over weeks Execution history unbounded Enable execution pruning
Container restarts, data gone Data not in a named volume Mount /home/node/.n8n persistently
502 through the proxy n8n not ready or wrong internal port Check logs, confirm proxy target n8n:5678

Hardening the instance

An n8n instance holds credentials for every service it touches. Treat it as one of the most sensitive machines you run, because in credential terms it usually is.

Never expose port 5678. All traffic goes through the reverse proxy over HTTPS. If you can reach http://your-ip:5678 from the internet, close it now.

Create the owner account immediately after first start. The window between container start and account creation is a window in which anyone who finds the URL can claim your instance.

Use n8n's built-in user management. Basic auth is deprecated and was never a real access control layer. Real accounts with real passwords, and enable multi-factor authentication.

Restrict SSH properly. Key-based authentication only, password auth disabled, root login disabled, and fail2ban watching the auth log. This is generic VPS hygiene and it applies here more than most places.

Think hard about the code node. Arbitrary JavaScript execution inside your automation platform is a powerful feature and a real attack surface. If multiple people have editor access, restrict who can create code nodes.

Keep the reverse proxy patched. Caddy handles TLS renewal automatically, but the container itself still needs updating.

Watch what community nodes you install. They run with the same privileges as n8n itself. Install from sources you can evaluate.

For a general hardening baseline on a fresh machine, our first ten things to do on a new Linux VPS covers the ground before n8n enters the picture.

Vertical infographic showing an n8n security checklist in three tiers: network layer with reverse proxy and firewall, application layer with user management and MFA, and data layer with encryption key backup and database security

When you need queue mode

By default n8n runs in main mode: a single process handles the editor, the API, and every workflow execution. Simple, and correct for most installations.

It becomes a problem when executions start queueing behind each other. Symptoms are recognisable. The editor becomes sluggish while workflows run. Long-running executions block short ones. A traffic spike produces webhook timeouts because the single process cannot keep up.

Queue mode splits the work. A main process handles the UI and accepts incoming triggers, Redis holds a job queue, and separate worker processes pull jobs and execute them. Workers scale horizontally, so throughput increases by adding workers rather than by buying a bigger machine.

The cost is complexity. You are now running Redis, managing worker processes, and debugging across multiple containers instead of reading one log stream.

The honest threshold: stay in main mode until you have a concrete symptom. Executions visibly queueing, webhook timeouts under load, or an editor that becomes unusable during runs. Most instances under a few thousand executions a day never need it.

If you do move, expect to move up a VPS tier at the same time. Redis plus multiple workers plus PostgreSQL plus n8n on a 4GB machine is tight.

Backups, updates, and the ops you now own

This is the part of self-hosting that gets skipped in every quickstart, and it is the part that determines whether your instance survives its second year.

Back up three things, not one. The PostgreSQL database, which holds workflows, credentials and execution history. The n8n data directory, mounted from /home/node/.n8n. And the encryption key, stored separately from both.

A pg_dump on a nightly cron, written to a directory that gets pushed offsite, is enough. Offsite matters, because a backup sitting on the same VPS protects you against nothing that actually kills a server. Applying the 3-2-1 backup rule here is not overkill given what the database contains.

Test a restore. An untested backup is a hypothesis. Restore into a throwaway container once, confirm workflows load and one credential decrypts, and you will know your key handling is correct before you need it to be.

Prune execution data. n8n stores every execution by default and the database grows forever. Set EXECUTIONS_DATA_PRUNE=true with a retention window, thirty days suits most teams, and consider saving only failed executions for high-frequency workflows. An unpruned instance gets slower every week and nobody connects the two.

Pin your image version. Running n8n:latest means an unattended docker compose pull can drop a breaking change into production. Pin a specific version, read the release notes, and upgrade deliberately.

Back up before every upgrade. Database migrations run on version changes and rolling back a partially migrated database without a backup is not a good evening.

Monitor something. At minimum, an uptime check on your domain and an alert on n8n's failed-execution workflow. Silent failure is the default state of a self-hosted automation instance, and workflows that stopped firing three weeks ago are discovered by accident.

None of this is difficult. It is maybe an hour of setup and twenty minutes a month afterwards. But it is real work, and it is the honest cost of the pricing you moved to self-hosting to escape.

FAQs

Is self-hosting n8n free?

The n8n Community Edition is free to self-host under the Sustainable Use License for internal business purposes, so there is no software fee. Your costs are the server, typically ₹800 to ₹2,000 a month for a production-capable VPS, plus a domain. Enterprise features such as SSO, log streaming and external secret management require a paid licence regardless of where you host.

What are the minimum server requirements for n8n?

A learning or personal instance runs on 1 vCPU and 2GB of RAM. The realistic production floor is 2 vCPU and 4GB, which comfortably handles n8n with PostgreSQL, a reverse proxy and moderate concurrency. Move to 4 vCPU and 8GB once you process large payloads, run many workflows concurrently, or adopt queue mode, since n8n holds workflow data in memory during execution.

Should I use SQLite or PostgreSQL for n8n?

Use PostgreSQL for anything beyond local testing. SQLite is the default and works for a single-user instance with minimal concurrency, but it allows only one writer, and concurrent workflow executions create lock contention that can corrupt the database. Choose PostgreSQL before your first install, because migrating after you have built workflows is disruptive and credentials do not always transfer cleanly.

What happens if I lose my n8n encryption key?

Every stored credential becomes permanently unreadable and must be re-entered by hand. The key encrypts credentials at rest and there is no recovery path without it. Set N8N_ENCRYPTION_KEY explicitly rather than letting n8n generate one, and store a copy outside the server in a password manager, separate from your database backups.

Why is my n8n webhook not triggering?

Almost always because WEBHOOK_URL is unset or wrong, so n8n generates webhook endpoints pointing at localhost that external services cannot reach. Set WEBHOOK_URL to your full public URL including protocol and trailing slash, alongside N8N_HOST and N8N_PROTOCOL. Then open a webhook node and confirm the displayed production URL uses your real domain.

Can I run n8n without Docker?

Yes, via npm on Node.js, but Docker is strongly preferred for production. Docker isolates dependencies, makes version pinning and rollback straightforward, and keeps upgrades to a pull and restart. A bare npm install ties you to the host's Node version and makes clean upgrades harder.

Do I need queue mode?

Not until you have a symptom. Queue mode splits execution into Redis-backed workers and is worth the added complexity only when executions visibly queue behind each other, webhooks time out under load, or the editor becomes unusable while workflows run. Most instances under a few thousand executions a day run fine in default main mode.

Is self-hosted n8n secure enough for customer data?

It can be, and the security depends entirely on your configuration. Keep n8n behind a reverse proxy with TLS, never expose the application port directly, use built-in user management with multi-factor authentication rather than deprecated basic auth, restrict SSH to key-based login, and back up the encryption key separately. The instance holds credentials for every connected service, so treat it as high-value infrastructure.

Can I resell n8n access to my clients?

Not under the Sustainable Use License without a commercial agreement. You may self-host freely for your own internal business purposes, including building and maintaining workflows on a client's own instance. Hosting n8n as a service for third parties or charging clients for access to an instance you run requires a commercial arrangement with n8n.

How do I stop my n8n database from growing forever?

Enable execution pruning with EXECUTIONS_DATA_PRUNE=true and set a retention window, with thirty days suiting most teams. For high-frequency workflows, configure them to save only failed executions rather than every run. Without pruning, execution history grows without limit, and instances that get progressively slower over months are usually suffering from this rather than from a resource shortage.

How much does self-hosted n8n cost compared to n8n Cloud?

Self-hosting costs your VPS, roughly ₹800 to ₹2,000 a month for a production-capable server, and that figure does not change with execution volume. Cloud plans price by execution, so the comparison depends entirely on how much you run. A single workflow firing every five minutes executes around 8,640 times a month, which is the kind of volume where self-hosting becomes clearly cheaper.

How do I upgrade n8n safely?

Back up the database and the data directory first, read the release notes for breaking changes, then pull the pinned new version and restart. Avoid running the latest tag in production, since an unattended pull can introduce a breaking change without warning. Version upgrades run database migrations, and rolling back a partially migrated database without a backup is not reliably possible.

Conclusion

Self-hosting n8n is a good decision for the right reasons and a frustrating one for the wrong reasons. The right reasons are volume, data control, and capability. The wrong reason is assuming that free software means free.

The install is twenty minutes. The operations are permanent.

What separates instances that run for years from instances that die in month four is unglamorous: PostgreSQL instead of SQLite, an encryption key stored somewhere other than the server, execution pruning switched on before the database bloats, a tested restore, and a pinned image version so nobody wakes up to an unplanned migration.

Get those five right and n8n is close to maintenance-free. Get them wrong and you will eventually re-enter forty API credentials by hand, which is a Saturday nobody plans for.

The sizing advice worth repeating: start at 2 vCPU and 4GB if this is going anywhere near production. The 2GB instances people recommend will run n8n right up until a workflow pulls a large payload, and then they will not.

HostCloud runs Linux VPS plans from ₹999 a month on NVMe storage with full root access, Indian data centres for lower latency on India-facing automations, and automated daily backups you can restore from the panel. If you would rather skip the Docker work entirely, our managed n8n hosting ships a hardened instance with PostgreSQL, TLS and backups already configured.

Related posts