The Price Difference That Pulls People to Self-Hosting
n8n Cloud starts at $20/month for 2,500 workflow executions. The Starter plan limits you in both executions and active workflows. At scale, cloud pricing reaches $50-120/month for growing teams. Against that, a $6/month VPS sounds compelling.
The $6/month VPS is real. But it is not the full picture. This article walks through everything that self-hosting actually costs — money and time.
Infrastructure Costs
Minimum Viable Setup
| Component | Minimum spec | Monthly cost (2026) |
|---|---|---|
| VPS (DigitalOcean/Hetzner/Linode) | 2 vCPU, 4 GB RAM | $12-18/mo |
| Managed Postgres (optional) | Smallest plan | $15-25/mo |
| Object storage for backups (S3/R2) | 10 GB | $0.23-$1.50/mo |
| Domain (amortised monthly) | Standard .com | $1/mo |
| SSL certificate | Let's Encrypt | Free (but requires renewal automation) |
If you run Postgres on the same VPS (not managed), add 1-2 GB RAM to your VPS requirement and lose the managed Postgres line. That brings the pure infrastructure cost to $14-20/month — similar to or less than n8n Cloud Starter.
The Hetzner Advantage
Hetzner CX22 (2 vCPU, 4 GB RAM) costs EUR 3.79/month (~$4.10 USD) as of March 2026. For self-hosters in Europe or with latency-tolerant workflows, this is the most cost-effective option. Bandwidth is generous (20 TB/month). Many n8n community members run production instances here.
The Hidden Costs
Reverse Proxy and SSL
n8n runs on port 5678 by default. You need a reverse proxy (Nginx or Caddy) to expose it on port 443 with SSL. Caddy handles Let's Encrypt automatically; Nginx requires Certbot configuration and a cron job for renewal.
Setup time: 30-90 minutes if you have done it before. 2-4 hours the first time. This is a one-time cost but it catches people off-guard.
Postgres vs SQLite
n8n ships with SQLite by default. For production, the n8n team strongly recommends Postgres. SQLite works but has no concurrent write support — if two workflows trigger simultaneously and both write to the database, you can get locking errors.
Setting up Postgres adds either $15-25/month (managed) or VPS resource overhead (self-managed). Many self-hosters skip this until they hit their first SQLite locking issue in production. Do not skip it for business-critical workflows.
Backups
You are responsible for your own backups. At minimum, back up:
- Your n8n database (Postgres dump or SQLite file) — daily
- Your n8n credentials (exported from n8n UI or via API) — weekly
- Your Docker Compose and environment files — on every change
A simple Postgres backup script piped to S3/R2 costs $0.23-$1.50/month in storage. The scripting time is free, but someone has to write and test it.
Updates
n8n releases updates frequently — roughly weekly minor versions, monthly major versions. Each update requires pulling the new Docker image and restarting the container. Breaking changes happen a few times a year.
Realistically, expect to spend 15-30 minutes per month on updates, plus occasional incident investigation when a workflow breaks after an update. Over a year that is 3-6 hours of maintenance.
The Real Cost: Your Time
| Activity | Estimated time (first year) | Recurs? |
|---|---|---|
| Initial setup (VPS, Docker, Nginx/Caddy, Postgres) | 4-8 hours | No |
| Monthly updates | 15-30 min/month = 3-6 hrs/year | Yes |
| Incident investigation (update breaks workflow, etc.) | 1-3 hrs/year (optimistic) | Yes |
| Backup setup and testing | 2-3 hours | Test annually |
| SSL renewal issues (Let's Encrypt edge cases) | 0-2 hours/year | Occasional |
If your time is worth $50/hour, the first-year setup cost alone is $200-400 in time. That is the cost you are trading against $20-50/month on n8n Cloud.
When Self-Hosting Is the Right Call
- You are processing sensitive data that cannot touch third-party cloud infrastructure (HIPAA, financial PII, etc.)
- You are running hundreds of thousands of executions monthly and cloud pricing becomes genuinely expensive
- You have DevOps capacity on the team and this fits into existing infrastructure management
- You need to run n8n behind a private network with no public internet exposure
- You want to customise n8n at the code level or run unreleased versions
When n8n Cloud Makes More Sense
- Your team is non-technical or does not have DevOps resources
- You are running fewer than 50,000 executions/month (Cloud pricing is competitive)
- You have had a production incident caused by infrastructure (database failure, disk full, OOM kill) and cannot tolerate it again
- You want guaranteed uptime SLAs for business-critical workflows
- Your primary concern is building workflows, not managing infrastructure
Minimum Production-Ready Docker Compose
This is the configuration the n8n documentation recommends for production self-hosting. It requires a Postgres instance and sets the key security and performance environment variables.
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
restart: always
ports:
- '127.0.0.1:5678:5678' # bind to localhost only; Nginx proxies externally
environment:
- N8N_HOST=your-domain.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://your-domain.com/
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY} # NEVER lose this
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=168 # keep 7 days of execution history
volumes:
- n8n_data:/home/node/.n8n
depends_on:
- postgres
postgres:
image: postgres:15
restart: always
environment:
- POSTGRES_DB=n8n
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
n8n_data:
postgres_data:
The N8N_ENCRYPTION_KEY encrypts all credentials stored in your database. If you lose this key, all stored credentials (API keys, OAuth tokens) become unrecoverable. Back it up separately from your database.