Zapier costs $30/month for 750 task runs. Make is cheaper but still per-task. Both make perfect sense until your automations start firing thousands of times — then the math flips hard. n8n is the open-source workflow tool that ends per-task pricing forever: same visual node-based editor, 400+ integrations, but you host it yourself and pay $7.99–$35.99/month for a VPS regardless of how many tasks run.

This guide deploys n8n with a PostgreSQL backend (not SQLite — Postgres survives restarts and scales), sets up Nginx with HTTPS for incoming webhook URLs, hardens the dashboard behind auth, and configures backups. The architecture, decisions, and gotchas matter more than the install commands — which is why this guide spends time on encryption keys, webhook URLs, and the 'why not SQLite' question that breaks more self-hosted n8n setups than anything else.

🐾 What you'll need:
  • A Linux VPS — Ubuntu 22.04 or Debian 12, 2 GB RAM minimum
  • A domain pointed at your VPS (n8n's webhook URLs need real HTTPS)
  • Roughly 30 minutes

For a turnkey n8n install with Postgres pre-configured, see our n8n VPS plans — instant deploy, no compose-file editing required.

1. When self-hosting n8n actually pays off

Run the numbers before committing:

Tasks per monthZapierMakeSelf-hosted n8n on OliveVPS
Under 500Free or $30/moFree or $9/mo$7.99/mo (Starter VPS)
2,000–5,000$50–$100/mo$29/mo$7.99–$15.99/mo
10,000+$150–$300/mo$50–$200/mo$15.99–$35.99/mo
100,000+$500+/mo$300+/mo$35.99/mo (Premium VPS)

The break-even is around 1,000–2,000 monthly tasks. Below that, Zapier's polish wins. Above that, self-hosted is dramatically cheaper — and you control the data, can run AI-heavy workflows with no per-token markup, and don't worry about platform policy changes.

2. Prepare the VPS

apt update && apt upgrade -y
apt install -y curl ca-certificates gnupg ufw

ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable

adduser n8n
usermod -aG sudo n8n
rsync --archive --chown=n8n:n8n ~/.ssh /home/n8n

3. Install Docker

install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  tee /etc/apt/sources.list.d/docker.list > /dev/null

apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
usermod -aG docker n8n

If you're new to Docker, our Docker setup tutorial covers daemon hardening.

4. Deploy n8n with Postgres

This is the most important section. Most n8n tutorials use SQLite — fast to set up, terrible for production. Workflows get corrupted on power loss, the file locks under load, backups are awkward. Use Postgres from day one.

Switch to the n8n user and create the project directory:

su - n8n
mkdir -p ~/n8n
cd ~/n8n

# Generate a random encryption key — this encrypts credentials at rest
# Save this somewhere safe! Losing it = losing all stored credentials.
ENCRYPTION_KEY=$(openssl rand -hex 32)
echo "ENCRYPTION_KEY=$ENCRYPTION_KEY" > ~/.n8n-secrets
chmod 600 ~/.n8n-secrets
echo "Saved your encryption key to ~/.n8n-secrets — back it up off the VPS!"

Create compose.yaml:

services:
  postgres:
    image: postgres:16-alpine
    container_name: n8n-postgres
    restart: unless-stopped
    environment:
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: CHANGE_THIS_TO_STRONG_PASSWORD
      POSTGRES_DB: n8n
    volumes:
      - ./postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 5s
      timeout: 5s
      retries: 10

  n8n:
    image: docker.n8n.io/n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    ports:
      - "127.0.0.1:5678:5678"
    volumes:
      - ./n8n-data:/home/node/.n8n
    environment:
      # Database
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_PORT: 5432
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: CHANGE_THIS_TO_STRONG_PASSWORD

      # Encryption (use the value you generated above)
      N8N_ENCRYPTION_KEY: "PASTE_YOUR_ENCRYPTION_KEY_HERE"

      # Public URL — critical for webhook URLs
      N8N_HOST: n8n.example.com
      N8N_PROTOCOL: https
      N8N_PORT: 5678
      WEBHOOK_URL: https://n8n.example.com/

      # Timezone
      GENERIC_TIMEZONE: UTC
      TZ: UTC

      # Logging
      N8N_LOG_LEVEL: info

Edit both POSTGRES_PASSWORD entries to match (use the same strong password), paste your encryption key into N8N_ENCRYPTION_KEY, and replace the domain. Then start:

docker compose up -d
docker compose logs -f

First boot takes ~30 seconds. When you see Editor is now accessible via: http://localhost:5678/, it's up.

5. Nginx reverse proxy + HTTPS

sudo apt install -y nginx certbot python3-certbot-nginx

sudo tee /etc/nginx/sites-available/n8n <<'EOF'
server {
    listen 80;
    server_name n8n.example.com;

    client_max_body_size 16M;   # Allow larger webhook payloads

    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_read_timeout 600s;
        proxy_send_timeout 600s;
    }
}
EOF

sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d n8n.example.com

Visit https://n8n.example.com — n8n's setup wizard greets you. Create the owner account (this is the admin). Pick a strong password.

6. Build your first workflow

Click + Add Workflow. n8n's editor is the visual node graph that made Zapier famous, but more powerful.

Drop a Schedule Trigger node (fires on cron) → HTTP Request node (calls an API) → IF node (branches on condition) → Slack node (posts a message).

Click Execute Workflow to test. Each node lights up green/red showing exactly what data flowed through. Active toggle → it runs on schedule.

For 400+ pre-built integrations: search the node palette. Notable ones: Gmail, Slack, Discord, Telegram, Sheets, Notion, Airtable, Postgres, MySQL, Stripe, OpenAI, Anthropic, HuggingFace, plus generic HTTP/Webhook/Cron for anything that doesn't have a dedicated node.

🐾 Skip the compose-file editing

Our n8n VPS plans deploy with Postgres pre-configured, the encryption key already generated, and HTTPS endpoints provisioned. From zero to first workflow in 5 minutes instead of 30.

See n8n VPS Plans →

7. Public webhooks

n8n's killer feature for integrations: every workflow gets a public HTTPS webhook URL. Stripe events, GitHub Actions triggers, Discord bot callbacks — anything that can POST to a URL becomes a workflow trigger.

Drop a Webhook node into a workflow. n8n generates two URLs:

The URL format is https://n8n.example.com/webhook/<uuid>. This is why we set WEBHOOK_URL correctly in the compose file — n8n needs to know its own public hostname.

If you misconfigure the webhook URL early on and create workflows with the wrong URL embedded, you'll have to manually update each one after the fact. Get this right before you build anything important.

8. Backups and credential security

Two things to back up: the encryption key (which decrypts stored credentials) and the Postgres database (which contains workflows, executions, credentials in encrypted form).

Encryption key first. It's already in ~/.n8n-secrets. Print it, save it to a password manager, mail it to yourself, write it on paper. Losing this key means losing every stored credential.

Postgres backups:

cat > /home/n8n/backup.sh <<'EOF'
#!/bin/bash
set -euo pipefail

cd /home/n8n/n8n
BACKUP_DIR=/home/n8n/backups
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
mkdir -p "$BACKUP_DIR"

# Database dump
docker compose exec -T postgres pg_dump -U n8n n8n | gzip > "$BACKUP_DIR/n8n-db-$TIMESTAMP.sql.gz"

# n8n config + binary data
tar -czf "$BACKUP_DIR/n8n-data-$TIMESTAMP.tar.gz" -C /home/n8n/n8n n8n-data

# Keep last 14 days
find "$BACKUP_DIR" -name '*.gz' -mtime +14 -delete

echo "Backup complete: $TIMESTAMP"
EOF

chmod +x /home/n8n/backup.sh

# Cron daily at 3 AM
crontab -e
# Add:
# 0 3 * * * /home/n8n/backup.sh >> /home/n8n/backup.log 2>&1

Push backups off the VPS — rclone to Backblaze B2 / Wasabi / S3. A backup that lives only on the VPS you're trying to protect against is not a backup.

9. Reference: scaling and licensing

Licensing — the fair-code question

n8n uses the Sustainable Use License — a "fair-code" license. Important constraints:

Most self-hosters are covered. The restriction targets companies that would white-label n8n and sell it as their own product.

Per-plan capacity

PlanWorkflowsDaily executionsNotes
Starter ($7.99, 2 GB)10–20~5,000Light workflows only — no AI nodes
Pro ($15.99, 4 GB)50–100~50,000Production setups with AI integration
Premium ($35.99, 8 GB)200+500,000+High-throughput, multi-user teams

AI workflows are RAM-heavy

OpenAI, Anthropic, and HuggingFace nodes load large payloads in memory. A single GPT-4-class workflow can consume 200–500 MB transiently. Plan for Pro or Premium if your automations are AI-heavy.

Queue mode for high throughput

Default n8n runs all workflows in the main process. For high-volume use (10,000+ daily executions), enable queue mode: add a Redis container and set EXECUTIONS_MODE=queue. Workers process the queue in parallel. Documented in detail in the n8n docs — covered briefly here because it's only worth it at real scale.

External Postgres for production

The compose file above runs Postgres alongside n8n. Fine for small setups. For real production, run Postgres on a separate VPS — survives Docker restarts independently, can be scaled separately. See our PostgreSQL setup guide for the standalone version.

FAQ

n8n vs Make vs Zapier — which one wins?

Zapier wins for ease (drag, drop, done — no infra). Make wins for complex branching and visual workflows. n8n wins when self-hosting matters: full data sovereignty, unlimited executions, no per-task pricing. The break-even is around 1,000–2,000 monthly tasks. Below that, Zapier is easier. Above that, n8n pays for itself within a month.

Can I import workflows from Zapier or Make?

No direct import. The workflow data formats are different. But the concepts translate — Zaps and Scenarios become workflows, triggers become Trigger nodes, actions become regular nodes. Most users rebuild rather than migrate, and it usually takes 30 minutes per non-trivial workflow.

How do I run AI-heavy workflows reliably?

The Pro plan minimum, ideally Premium for serious GPT-4/Claude usage. AI nodes are RAM-heavy. Enable queue mode (Redis + worker container) so AI calls don't block the main process. Also: set rate limits on the API node — burning through OpenAI's TPM limits makes everything fail.

Is the SQLite default really that bad?

For development and learning, SQLite is fine. For production with concurrent workflows, regular webhook traffic, or anything you care about — yes, it's that bad. SQLite locks aggressively under writes, corrupts on power loss, and is awkward to back up. Use Postgres from day one.

Can multiple team members use one n8n install?

Yes — n8n has built-in multi-user support with role-based access (Owner / Admin / Member). Each user has their own workflows; shared credentials work across users with permissions. The Starter plan handles small teams (~5 users); Pro is comfortable for 10–20 active users.

What happens if I lose my encryption key?

Every stored credential becomes unreadable. The workflows still load (their structure isn't encrypted) but they can't authenticate to external services. You'll need to re-enter every API key, OAuth token, and password manually. Back up the encryption key separately from the database — they should never sit in the same backup blob.

🐱
OliveVPS Team

We run n8n in production for support-ticket triage, alert routing, and lead-capture automations. The Pro plan handles ~30,000 monthly executions including OpenAI-powered classification — well under the Zapier-equivalent monthly bill which would be ~$200.