Self-hosted n8n with webhooks that just answer.
First month $1, then the normal monthly price. One per customer.
n8n on a KVM VPS with full root and NVMe RAID10, in Amsterdam or New York. Run it with docker compose and Postgres, give it a domain with a real certificate, and stop paying per execution. Unlimited traffic, a fixed monthly price, and your credentials stay on your own disk.
Transparent pricing
Plans and prices
| Plan | vCPU | Memory | NVMe | Traffic | Monthly | 1 year | |
|---|---|---|---|---|---|---|---|
| Standard | |||||||
| S-2Standard | 1vCPU | 2 GBMemory | 30 GBNVMe RAID10 | UnlimitedTraffic | $7.99/moFirst month $1 | $7.19/mo on 1 year | Start for $1 |
| S-4Standard | 2vCPU | 4 GBMemory | 60 GBNVMe RAID10 | UnlimitedTraffic | $13.99/moFirst month $1 | $12.59/mo on 1 year | Start for $1 |
| S-8Standard | 3vCPU | 8 GBMemory | 120 GBNVMe RAID10 | UnlimitedTraffic | $24.99/moFirst month $1 | $22.49/mo on 1 year | Start for $1 |
| S-16Standard | 4vCPU | 16 GBMemory | 240 GBNVMe RAID10 | UnlimitedTraffic | $44.99/moFirst month $1 | $40.49/mo on 1 year | Start for $1 |
| S-32Standard | 8vCPU | 32 GBMemory | 480 GBNVMe RAID10 | UnlimitedTraffic | $84.99/moFirst month $1 | $76.49/mo on 1 year | Start for $1 |
| S-64Standard | 16vCPU | 64 GBMemory | 720 GBNVMe RAID10 | UnlimitedTraffic | $159.99/moFirst month $1 | $143.99/mo on 1 year | Start for $1 |
| Dedicated CPU | |||||||
| D-4Dedicated | 1vCPU | 4 GBMemory | 45 GBNVMe RAID10 | UnlimitedTraffic | $37.00/moFirst month $1 | $31.45/mo on 1 year | Start for $1 |
| D-8Dedicated | 4vCPU | 8 GBMemory | 90 GBNVMe RAID10 | UnlimitedTraffic | $69.00/moFirst month $1 | $58.65/mo on 1 year | Start for $1 |
| D-16Dedicated | 4vCPU | 16 GBMemory | 160 GBNVMe RAID10 | UnlimitedTraffic | $118.00/moFirst month $1 | $100.30/mo on 1 year | Start for $1 |
| D-32Dedicated | 6vCPU | 32 GBMemory | 220 GBNVMe RAID10 | UnlimitedTraffic | $215.00/mo | $182.75/mo on 1 year | Deploy D-32 |
| D-64Dedicated | 10vCPU | 64 GBMemory | 400 GBNVMe RAID10 | UnlimitedTraffic | $377.00/mo | $320.45/mo on 1 year | Deploy D-64 |
| High Memory | |||||||
| H-64High Memory | 8vCPU | 64 GBMemory | 480 GBNVMe RAID10 | UnlimitedTraffic | $249.00/mo | $211.65/mo on 1 year | Deploy H-64 |
| H-128High Memory | 16vCPU | 128 GBMemory | 960 GBNVMe RAID10 | UnlimitedTraffic | $459.00/mo | $390.15/mo on 1 year | Deploy H-128 |
| H-192High Memory | 24vCPU | 192 GBMemory | 1.4 TBNVMe RAID10 | UnlimitedTraffic | $669.00/mo | $568.65/mo on 1 year | Deploy H-192 |
Why n8n belongs on a VPS you own.
n8n is a single Node process that talks to a database and listens for webhooks. That is a small, well-understood workload, and it is a good fit for a VPS with a fixed price.
No execution meter
A workflow that runs every minute is 43,200 executions a month. On a VPS that costs the same as one that runs once a day. An S-4 (2 vCPU, 4 GB, 60 GB NVMe) at €11.99 a month ($13.99) handles a few hundred executions a day with Postgres alongside.
Credentials stay on your disk
API keys for your CRM, mail provider and databases are stored encrypted in the n8n database on NVMe RAID10 in our Amsterdam or New York facility, under a key only you hold. Nothing leaves the box unless a workflow sends it.
Webhooks that respond in milliseconds
Stripe, GitHub, Typeform and chat bots all want a fast 200 back. Amsterdam is 8.5 ms from Frankfurt and 9.3 ms from Paris; New York is 4-7 ms from Philadelphia. n8n itself answers a webhook in a few milliseconds once it is warm.
Root for the awkward integrations
Community nodes, a local Python script called from an Execute Command node, a headless browser next door, a cron job that cleans up: all possible because you have full root and your own kernel on KVM.
Which plan for this workload.
Executions per day and what those executions do decide the size. A workflow that fetches one JSON document is nothing; one that processes a 50 MB file or runs a code node in a loop is not.
| Setup | Plan | Why |
|---|---|---|
| n8n alone with SQLite, a few scheduled workflows, dozens of executions a day | S-2 | 1 vCPU and 2 GB is enough for the n8n process. Prune execution data so the 30 GB disk stays healthy. |
| n8n with Postgres and Caddy, webhooks, a few hundred executions a day | S-4 | 2 vCPU keeps webhooks responsive while a scheduled workflow runs. 4 GB leaves Postgres a cache. |
| Queue mode: main, one or two workers, Redis, Postgres, thousands of executions a day | S-8 | 3 vCPU and 8 GB spread the load over workers. 120 GB for execution history. |
| Many parallel workers, large files, AI nodes with big payloads | S-16 | 4 vCPU and 16 GB. Each worker holds its payload in memory, so RAM scales with concurrency. |
| Heavy code nodes every minute, latency that must not jitter | D-8 | Four cores pinned 1:1. Shared vCPU is fine for bursts; sustained CPU every minute is better on a dedicated core. |
Our rule of thumb: n8n on its own runs on the S-2 (1 vCPU, 2 GB, 30 GB NVMe) at €6.99 a month ($7.99). Add Postgres and a few hundred executions a day and the S-4 is the right start. Queue mode with Redis, where a main process hands work to separate worker containers, wants the S-8 (3 vCPU, 8 GB, 120 GB NVMe) at €21.99 a month ($24.99), because every worker is a full Node process with its own memory.
The honest limit on the small plans is disk, and n8n is good at filling it. By default every execution stores its full input and output data. A workflow that polls an API every minute writes a row with its payload sixty times an hour. Set the pruning variables shown below and the S-2 stays fine for months. If you outgrow a plan, we resize RAM and vCPU in place with the data and IP unchanged, usually with one short reboot. Extra disk is +100 GB NVMe for €11.00 a month on Standard plans.
Setting it up on BuyVPS.
Step 1: order the VPS and set DNS
Choose Ubuntu 24.04 at checkout. The VPS is ready 30 to 60 seconds after payment. Create an A record such as n8n.example.com pointing at the IPv4 address, and an AAAA record from your /64 if you use IPv6. Caddy needs the record to resolve before it can get a certificate.
Step 2: install Docker Engine
Use the official repository so compose v2 is included. Full apt commands are on our Linux VPS pages; the short version:
apt update && apt install -y ca-certificates curl install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc echo "deb [signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable" > /etc/apt/sources.list.d/docker.list apt update && apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin ufw allow 22/tcp && ufw allow 80/tcp && ufw allow 443/tcp && ufw enable
Step 3: write the .env file
Generate the encryption key once, store it somewhere safe outside the server, and never change it. It encrypts every credential in the database.
mkdir -p /opt/n8n && cd /opt/n8n cat > .env <<'ENV' N8N_HOST=n8n.example.com N8N_PROTOCOL=https WEBHOOK_URL=https://n8n.example.com/ N8N_ENCRYPTION_KEY=REPLACE_WITH_openssl_rand_-hex_32 GENERIC_TIMEZONE=Europe/Amsterdam TZ=Europe/Amsterdam POSTGRES_PASSWORD=REPLACE_WITH_A_LONG_PASSWORD EXECUTIONS_DATA_PRUNE=true EXECUTIONS_DATA_MAX_AGE=168 ENV chmod 600 .env
Step 4: the compose file and the Caddyfile
services:
postgres:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: n8n
volumes: ["pg_data:/var/lib/postgresql/data"]
n8n:
image: docker.n8n.io/n8nio/n8n
restart: unless-stopped
env_file: .env
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_USER: n8n
DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
DB_POSTGRESDB_DATABASE: n8n
volumes: ["n8n_data:/home/node/.n8n"]
depends_on: [postgres]
caddy:
image: caddy:2
restart: unless-stopped
ports: ["80:80", "443:443"]
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
volumes:
pg_data:
n8n_data:
caddy_data:
# Caddyfile
n8n.example.com {
reverse_proxy n8n:5678
}
Step 5: start it and create the owner account
docker compose up -d docker compose logs -f n8n
Open https://n8n.example.com, create the owner account, and add a Webhook node to a test workflow. The URL it shows must start with your domain, not localhost. Send a request to it with curl to confirm the round trip works.
Step 6: updates and backups
Updating is a pull and a restart. Back up the database dump and the .env file together; one without the other is useless.
docker compose pull && docker compose up -d docker compose exec postgres pg_dump -U n8n n8n | gzip > n8n-$(date +%F).sql.gz
Pitfalls we see, and how to avoid them.
The SQLite file grows until the disk is full
Without Postgres and without pruning, execution data lands in one SQLite file that never shrinks. On a 30 GB disk that ends with n8n refusing to start. Set EXECUTIONS_DATA_PRUNE and EXECUTIONS_DATA_MAX_AGE from day one, and move to Postgres as soon as webhooks matter.
Webhook URLs with localhost in them
If WEBHOOK_URL is missing, n8n builds webhook addresses from what it sees inside the container. External services then get a URL that points nowhere. Set WEBHOOK_URL to the public HTTPS address with a trailing slash and restart.
Schedules fire at the wrong hour
Containers run in UTC by default. A cron trigger set for 08:00 then fires at 08:00 UTC. Set GENERIC_TIMEZONE for n8n and TZ for the container to the same zone. Check the time on the first scheduled run rather than trusting the setting.
Updating without a backup of the key
Upgrades occasionally change the database schema, and a rollback needs a matching dump. Worse is losing N8N_ENCRYPTION_KEY: every stored credential becomes unreadable. Keep the key in a password manager and the dump off the server. Our backup add-on at 20 to 60 percent of the plan price covers the whole disk.
Pick the region closest to your users.
Webhooks come from wherever your users and their tools are, and most API calls go to large providers with endpoints on both continents. Amsterdam is AMS-IX adjacent and 9.0 ms from London. New York is in the Hudson Street carrier hotel, 7-12 ms from Washington DC.
Questions about running n8n on a VPS.
Is the S-2 enough for n8n?
Yes, for n8n on its own with the default SQLite database and a handful of workflows. Turn on execution pruning so the 30 GB disk does not fill. As soon as you add Postgres and rely on webhooks, the S-4 is the better start.
Do I need Postgres, or is SQLite fine?
SQLite works for a personal instance. Postgres is the right choice once several workflows run at the same time, because SQLite locks the whole file on writes. Queue mode requires Postgres. Switching later means exporting workflows and credentials, so we start with Postgres on anything beyond a test.
When do I need queue mode?
When a single n8n process cannot keep up: webhooks time out while a long workflow runs, or executions pile up. Queue mode adds Redis and one or more worker containers, and the S-8 is the plan where that layout has room. Most instances never need it.
How do I get HTTPS for webhooks?
Put Caddy or Traefik in front of n8n on port 5678 with an A record pointing at the VPS. Caddy requests the Let's Encrypt certificate on the first request and renews it. Set WEBHOOK_URL to the https address so n8n hands out the correct URLs.
How do I update n8n safely?
Take a database dump, confirm the encryption key is stored elsewhere, then run docker compose pull and docker compose up -d. Read the release notes for breaking changes first. Pin a version tag in the compose file if you want to control when updates happen.
Where is the official documentation?
At n8n.io, including the environment variables used above. Our part is the VPS, the network and the disk; the n8n team documents the application.
Deploy a measured VPS
From $6.79/mo on a 2-year term. KVM on AMD EPYC, NVMe RAID10, ECC memory. No setup fee, cancel monthly.
30-day performance guarantee. Not satisfied? Full refund, no admin fee. How it works