Day 256 of the year: Programmers' Day. 10% off every month for as long as you keep your server. code DAY256. Claim 10% Programmers' Day: 10%: DAY256 Claim 10%
Skip to content
n8n automation

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.

Provisioning
30-60 safter payment
Latency
9.0 msAmsterdam to London
pgbench
7,364 TPS2 vCPU/4 GB dedicated
Traffic
Unlimitedno bandwidth bill
Plan
S-2 alone, S-4 with Postgres
1 vCPU, 2 GB and 30 GB NVMe for n8n on its own. 2 vCPU, 4 GB and 60 GB for n8n with Postgres and a few hundred executions a day.
Region
Amsterdam or New York
Same price. Put n8n where the APIs it calls most are, or where your users trigger webhooks from. The two regions are 75-90 ms apart.
OS
Ubuntu 24.04 LTS
Docker Engine from the official apt repository. Debian 13 is equally fine.
Stack
n8n, Postgres 16, Caddy
Three containers in one compose file. Caddy terminates TLS and proxies to n8n on port 5678. Postgres replaces the default SQLite file.
Domain
n8n.example.com with WEBHOOK_URL set
One A record and the WEBHOOK_URL variable. Without it, n8n hands out webhook URLs with localhost in them.
Expect
Queue mode from the S-8 up
Main process, one or more workers and Redis fit on 3 vCPU and 8 GB when executions climb into the thousands a day.

Transparent pricing

Plans and prices

Monthly price, no setup fee
Day 256 of the year: Programmers' Day. 10% off every month for as long as you keep your server.DAY256Start a VPS with this code
1:2 to 1:4Shared vCPU on EPYC Milan, capped at one to four shares per node, with the node headroom left unsold.
PlanvCPUMemoryNVMeTrafficMonthly1 year
Standard
S-2Standard1vCPU2 GBMemory30 GBNVMe RAID10UnlimitedTraffic$7.99/moFirst month $1$7.19/mo on 1 yearStart for $1
S-4Standard2vCPU4 GBMemory60 GBNVMe RAID10UnlimitedTraffic$13.99/moFirst month $1$12.59/mo on 1 yearStart for $1
S-8Standard3vCPU8 GBMemory120 GBNVMe RAID10UnlimitedTraffic$24.99/moFirst month $1$22.49/mo on 1 yearStart for $1
S-16Standard4vCPU16 GBMemory240 GBNVMe RAID10UnlimitedTraffic$44.99/moFirst month $1$40.49/mo on 1 yearStart for $1
S-32Standard8vCPU32 GBMemory480 GBNVMe RAID10UnlimitedTraffic$84.99/moFirst month $1$76.49/mo on 1 yearStart for $1
S-64Standard16vCPU64 GBMemory720 GBNVMe RAID10UnlimitedTraffic$159.99/moFirst month $1$143.99/mo on 1 yearStart for $1
Dedicated CPU
D-4Dedicated1vCPU4 GBMemory45 GBNVMe RAID10UnlimitedTraffic$37.00/moFirst month $1$31.45/mo on 1 yearStart for $1
D-8Dedicated4vCPU8 GBMemory90 GBNVMe RAID10UnlimitedTraffic$69.00/moFirst month $1$58.65/mo on 1 yearStart for $1
D-16Dedicated4vCPU16 GBMemory160 GBNVMe RAID10UnlimitedTraffic$118.00/moFirst month $1$100.30/mo on 1 yearStart for $1
D-32Dedicated6vCPU32 GBMemory220 GBNVMe RAID10UnlimitedTraffic$215.00/mo$182.75/mo on 1 yearDeploy D-32
D-64Dedicated10vCPU64 GBMemory400 GBNVMe RAID10UnlimitedTraffic$377.00/mo$320.45/mo on 1 yearDeploy D-64
High Memory
H-64High Memory8vCPU64 GBMemory480 GBNVMe RAID10UnlimitedTraffic$249.00/mo$211.65/mo on 1 yearDeploy H-64
H-128High Memory16vCPU128 GBMemory960 GBNVMe RAID10UnlimitedTraffic$459.00/mo$390.15/mo on 1 yearDeploy H-128
H-192High Memory24vCPU192 GBMemory1.4 TBNVMe RAID10UnlimitedTraffic$669.00/mo$568.65/mo on 1 yearDeploy H-192
Prices in USD. Code DAY256 gives 10% off every month for as long as you keep your server, on monthly and yearly terms.

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.

Amsterdam, for Europe
New York, for North America
See all locations

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.

Ready to deploy

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