If you're running more than a few thousand automated tasks per month, you're almost certainly overpaying. Big time.
Here's the deal: self-host n8n on a Hetzner VPS for $4.49/month and get unlimited workflow executions. The same capacity on Zapier costs upwards of $1,500/month. On n8n Cloud, you hit $20/month for just 2,500 executions and start paying per-execution after that.
I've been running n8n self-hosted across production projects since early 2025. This guide walks through the exact setup I use — including the gotchas the official docs gloss over.
n8n Cloud vs Self-Hosted: Which Should You Choose?
Before we dive into setup, let's be honest about the tradeoffs. n8n offers a managed cloud tier, but self-hosting is dramatically cheaper at scale.
Self-hosted is better if:
- You run high volume. At 5,000+ executions/month, self-hosting becomes cheaper than any paid plan.
- Data privacy matters. Your data never touches a third-party server. For healthcare, finance, or internal tools, this is non-negotiable.
- You need custom code. Self-hosted lets you install any npm package, use custom nodes, and run arbitrary Python or JavaScript.
- You want unlimited webhooks. No cap on active webhooks, no per-endpoint pricing.
- AI workflows. Native Claude, OpenAI GPT, and LangChain nodes work identically to cloud — you just bring your own API keys.
n8n Cloud is better if:
- You don't want to manage servers. No SSH, no Docker, no Nginx configs.
- You need official support. Enterprise plans come with SLAs.
- Auto-updates matter. Cloud gets new features and security patches immediately.
- You're under 2,500 executions/month. The $20 Starter plan may be cheaper than your time spent setting up a VPS.
- You want the free tier. n8n Cloud's free tier gives 1,000 executions/month — great for prototyping.
Pricing Comparison
| Plan | Monthly Cost | Executions | Active Workflows |
|---|---|---|---|
| n8n Cloud Free | $0 | 1,000 | 5 |
| n8n Cloud Starter | $20/mo | 2,500 | 20 |
| n8n Cloud Pro | $50/mo | 10,000 | 50 |
| n8n Cloud Enterprise | Custom | Custom | Unlimited |
| Self-Hosted (Hetzner CX22) | $4.49/mo | Unlimited | Unlimited |
At 10,000 executions/month, n8n Cloud costs $50/month while self-hosting costs $4.49/month plus your time. At 50,000 executions, Cloud jumps to custom enterprise pricing while self-hosting stays flat. The math is brutal.
Full Cost Breakdown
Here's the real monthly cost of running n8n yourself:
| Item | Cost | Notes |
|---|---|---|
| Hetzner CX22 VPS (2 vCPU, 4GB RAM, 40GB SSD) | $4.49/mo | Best price-to-performance in 2026 |
| Domain name (amortized) | ~$1/mo | $10-12/year via Cloudflare or Namecheap |
| SSL certificate | Free | Let's Encrypt via Certbot |
| Docker & Docker Compose | Free | Open source |
| n8n software | Free | MIT-licensed open source |
| PostgreSQL (optional, in Docker) | Free | Better than SQLite for production |
| Total | ~$5.50/mo |
Add backups if you want them. I use a cron job that rsyncs to Backblaze B2 for about $0.50/month extra. Still under $7/month total for a production-grade automation server.
Best VPS for n8n in 2026: Hetzner Deep-Dive
I've tested n8n on DigitalOcean, Linode, Vultr, and Hetzner. For n8n specifically, Hetzner is the clear winner on price-to-performance.
Hetzner Pricing (EUR, 2026)
| Plan | vCPU | RAM | Storage | Price/Month | Best For |
|---|---|---|---|---|---|
| CX12 | 1 | 2GB | 20GB SSD | €3.29 (~$3.59) | Light / testing |
| CX22 | 2 | 4GB | 40GB SSD | €4.11 (~$4.49) | Sweet spot for n8n |
| CX32 | 2 | 8GB | 80GB SSD | €7.41 (~$8.09) | Heavy AI / high volume |
| CX42 | 4 | 16GB | 160GB SSD | €14.41 (~$15.74) | Multi-service / enterprise |
My recommendation: Start with the CX22 at €4.11/month. It handles dozens of workflows simultaneously, runs PostgreSQL alongside n8n in Docker, and leaves headroom for growth. If you're running heavy AI workflows (LangChain chains, large model inference), bump to the CX32 for 8GB RAM.
Hetzner's data centers are in Germany (Nuremberg) and Finland (Helsinki), plus a US location. For latency-sensitive webhook use, choose the closest region.
Get started with Hetzner
The CX22 is €4.11/month — best deal in cloud hosting for n8n. You get a dedicated IPv4, IPv6, and free private networking.
Check Hetzner Pricing →Step-by-Step: Self-Host n8n with Docker Compose
This is the exact setup I run in production. We'll use Docker Compose with PostgreSQL for durability, Nginx as a reverse proxy, and Let's Encrypt for SSL.
Prerequisites
- A Hetzner VPS (or any Linux server) with Ubuntu 22.04 or 24.04
- A domain name pointed at your server's IP (e.g., n8n.yourdomain.com → A record)
- SSH access to your server
- Basic command-line comfort (don't worry — I'll show every command)
Step 1: Initial Server Setup
SSH into your server and run these as root or a sudo user:
# Update packages
sudo apt update && sudo apt upgrade -y
# Install essential tools
sudo apt install -y curl wget git ufw
# Set up firewall — allow SSH, HTTP, and HTTPS only
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
# Verify your hostname is set
hostnamectl set-hostname n8n-server
Don't skip the firewall. Without it, your n8n instance on port 5678 is exposed to the entire internet until you set up the reverse proxy.
Step 2: Install Docker and Docker Compose
# Install Docker using the official convenience script
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add your user to the docker group (so you don't need sudo)
sudo usermod -aG docker $USER
# Apply group changes without logging out
newgrp docker
# Verify Docker
docker --version
# Install Docker Compose v2 (comes bundled with Docker now)
docker compose version
After this, log out and back in for the group changes to stick permanently.
Step 3: Create the Docker Compose Setup
This is the production-ready setup. We use PostgreSQL instead of SQLite because SQLite doesn't handle concurrent writes well — if you have multiple workflows running, you'll eventually hit lock errors.
# Create project directory
mkdir -p ~/n8n-docker && cd ~/n8n-docker
# Create the docker-compose.yml file
nano docker-compose.yml
Paste this configuration:
version: '3.8'
services:
postgres:
image: postgres:16-alpine
restart: always
environment:
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=<your-strong-password>
- POSTGRES_DB=n8n
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n"]
interval: 10s
timeout: 5s
retries: 5
n8n:
image: n8nio/n8n:latest
restart: always
depends_on:
postgres:
condition: service_healthy
ports:
- "127.0.0.1:5678:5678"
environment:
- N8N_DATABASE_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=<your-strong-password>
- DB_POSTGRESDB_DATABASE=n8n
- N8N_ENCRYPTION_KEY=<generate-a-random-32-char-key>
- N8N_CONFIG_FILES=/home/node/.n8n/config.json
- N8N_SECURE_COOKIE=false
- WEBHOOK_URL=https://n8n.yourdomain.com
- GENERIC_TIMEZONE=UTC
volumes:
- n8n_data:/home/node/.n8n
- ./shared:/files
volumes:
postgres_data:
n8n_data:
Important: Replace the placeholders:
<your-strong-password>— generate one withopenssl rand -base64 32<generate-a-random-32-char-key>— useopenssl rand -hex 32n8n.yourdomain.com— your actual domain
Note the 127.0.0.1:5678:5678 port mapping. This binds n8n to localhost only — it's not accessible from the outside internet until we set up Nginx. This is a critical security measure.
Step 4: Launch n8n
# Start everything
docker compose up -d
# Check it's running
docker compose ps
# View logs
docker compose logs -f n8n
After a minute, you should see n8n's startup message. It's now running on http://localhost:5678 — but you can't reach that from your browser yet. Let's fix that.
Step 5: Set Up Nginx as a Reverse Proxy
# Install Nginx
sudo apt install -y nginx
# Create the site config
sudo nano /etc/nginx/sites-available/n8n
Add this configuration:
server {
listen 80;
server_name n8n.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:5678;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Host $host;
proxy_buffering off;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
}
Then enable the site:
# Enable the site
sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
# Test the config
sudo nginx -t
# Restart Nginx
sudo systemctl reload nginx
At this point, http://n8n.yourdomain.com should show the n8n setup screen. But we're not done — never run n8n over plain HTTP in production.
Step 6: Add SSL with Let's Encrypt
# Install Certbot
sudo apt install -y certbot python3-certbot-nginx
# Get SSL certificate (this auto-modifies your Nginx config)
sudo certbot --nginx -d n8n.yourdomain.com
# Follow the prompts — choose to redirect HTTP to HTTPS
# Verify auto-renewal works
sudo certbot renew --dry-run
Let's Encrypt certificates expire after 90 days, but Certbot sets up a systemd timer that auto-renews them. You can verify with systemctl list-timers | grep certbot.
After this, your n8n instance is accessible securely at https://n8n.yourdomain.com with a valid SSL certificate.
Step 7: Production Hardening
Before you start building real workflows, lock things down:
Enable n8n Basic Authentication
# Stop the containers
cd ~/n8n-docker
docker compose down
# Edit docker-compose.yml and add these env vars under n8n:
# - N8N_BASIC_AUTH_ACTIVE=true
# - N8N_BASIC_AUTH_USER=admin
# - N8N_BASIC_AUTH_PASSWORD=<strong-password>
# Then restart
docker compose up -d
Without basic auth, anyone who discovers your n8n URL can access your workflows and credentials. This is the single most important security step.
Set Up Automated Backups
# Create a backup script
sudo nano /usr/local/bin/backup-n8n.sh
# Paste:
#!/bin/bash
BACKUP_DIR="/backups/n8n"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
# Backup PostgreSQL database
docker exec n8n-docker-postgres-1 pg_dump -U n8n n8n > $BACKUP_DIR/n8n_db_$TIMESTAMP.sql
# Backup n8n data volume
docker run --rm -v n8n-docker_n8n_data:/data -v $BACKUP_DIR:/backup alpine tar czf /backup/n8n_data_$TIMESTAMP.tar.gz -C /data .
# Keep last 7 days of backups
find $BACKUP_DIR -type f -mtime +7 -delete
# Make it executable
sudo chmod +x /usr/local/bin/backup-n8n.sh
# Add to crontab (runs daily at 3am)
sudo crontab -e
# Add: 0 3 * * * /usr/local/bin/backup-n8n.sh
For off-site backups, rsync the backups directory to Backblaze B2, S3, or any object storage service.
Additional Hardening Tips
- SSH key only: Disable password-based SSH login. Edit
/etc/ssh/sshd_configand setPasswordAuthentication no. - Fail2ban: Install fail2ban to block brute-force SSH attempts:
sudo apt install fail2ban. - Regular updates: Run
docker compose pullanddocker compose up -dweekly to get the latest n8n security patches. - Resource limits: Add
deploy: resources: limits: memory: 512Mto the n8n service in docker-compose.yml to prevent runaway workflows from OOMing your server. - Encryption key: Store
N8N_ENCRYPTION_KEYin a.envfile, not in docker-compose.yml directly. Docker Compose reads.envautomatically.
Pros and Cons of Self-Hosting n8n
Let's be honest — self-hosting isn't all sunshine. Here's the real trade-off:
Pros ✅
- Unlimited everything. No execution caps, no active workflow limits, no webhook restrictions.
- Dramatically cheaper. $4.49/month vs $50-500/month for equivalent commercial plans.
- Full data privacy. Every credential, every data payload, every log stays on your hardware.
- Complete control. Install any npm package, run custom JavaScript/Python nodes, modify the codebase.
- No vendor lock-in. Your workflows are stored in a standard PostgreSQL database. You can migrate anywhere.
- AI node support. All AI features (Claude, GPT, LangChain) work identically to cloud. Just add API keys.
Cons ❌
- You're the sysadmin. Updates, backups, monitoring, and troubleshooting are 100% your responsibility.
- No official support. When something breaks, you're debugging it yourself or relying on GitHub issues and community forums.
- Setup time. Count on 1-2 hours for initial setup, longer if you're new to Linux and Docker.
- Potential downtime. Your uptime depends on your VPS provider and your own config quality. No SLA.
- Security overhead. You must keep the server patched, the Docker images updated, and firewall rules correct.
- Limited advanced features. Some n8n Cloud features (like advanced logging, team management, and SSO) require the enterprise self-hosted plan or don't exist in the open-source edition.
- No mobile app. The n8n mobile companion app only works with n8n Cloud (or the enterprise self-hosted plan).
Honest Verdict
After running n8n self-hosted through multiple production projects, here's where I land:
Self-host n8n if: You're comfortable with SSH and Docker, you need more than 5,000 executions per month, or data privacy is a real concern. The savings are enormous — you're looking at $50-60/year vs $600-6,000/year for equivalent cloud automation.
Use n8n Cloud if: You have zero interest in server management, you're prototyping, or your automation needs are modest (under 2,500 executions/month). The $20 Starter plan is fine for small teams, and the free tier covers testing.
The grey zone: If you're running 3,000-5,000 executions/month and your time is worth $100+/hour, Cloud may be a better deal when you factor in setup and maintenance time. At 10,000+ executions, self-hosting is a no-brainer even with the sysadmin tax.
My personal setup: Hetzner CX22 ($4.49/month), Docker Compose with PostgreSQL, automated daily backups to B2. I spend roughly 15 minutes per month on maintenance — pulling updates and checking logs. For that, I get unlimited automations across a dozen projects. The math works.
Frequently Asked Questions
How much does it cost to self-host n8n in 2026?
Around $5-7/month total. A Hetzner CX22 VPS costs $4.49/month, a domain amortizes to ~$1/month, and everything else (Docker, n8n, PostgreSQL, SSL) is free. At scale, you might add $0.50/month for off-site backups.
What server specs do I need for n8n?
For light use: 1 vCPU, 1GB RAM works. For real production use: 2 vCPU, 4GB RAM is the sweet spot (Hetzner CX22). For AI-heavy workflows with Claude or GPT nodes: 2 vCPU, 8GB RAM or more.
Is self-hosted n8n better than n8n Cloud?
It depends entirely on your use case. Self-hosting is vastly cheaper at scale and gives you full data control. The Cloud version saves you server management time and provides official support. See the comparison section above for details.
Can I use Docker Compose to set up n8n?
Yes, and it's the recommended method for production. A proper setup includes n8n, a PostgreSQL database, environment variables for encryption and auth, and a reverse proxy (Nginx or Traefik) for SSL termination.
How do I secure my self-hosted n8n instance?
Essential measures: HTTPS via Let's Encrypt, basic authentication enabled, a strong N8N_ENCRYPTION_KEY, firewall configured to only allow ports 22/80/443, regular Docker updates, and automated daily backups.
What VPS provider is best for n8n?
Hetzner offers the best price-to-performance in 2026 with the CX22 at €4.11/month. DigitalOcean is a good alternative if you prefer their interface, but you pay more for less (1GB RAM droplet at $6/month). Avoid ultra-budget providers — the reliability isn't worth the savings for a production automation server.
Start self-hosting n8n today
Download n8n free and open-source, then set it up on your own server in under an hour. No limits, no per-task pricing, no data leaving your control.
Download n8n Free →