Running n8n on SQLite is fine for experiments. For production traffic, use Postgres, a reverse proxy with WebSocket/SSE support, TLS, and backups. This guide walks through a practical stack on a VPS (Hetzner, DigitalOcean, etc.).
A small VPS plus Compose is enough for many self-hosted n8n workloads.
Why SQLite becomes a problem
SQLite is single-file and easy, but concurrent writes, large execution history, and multi-instance setups hurt. n8n documents Postgres as the production database for a reason.
Minimum architecture
| Component | Role |
|---|---|
| VPS (2 vCPU / 4GB+) | Host |
| Docker + Compose | Runtime |
| Postgres 15/16 | Primary DB |
| n8n | Automation engine |
| NGINX + Certbot | TLS + WebSockets |
NGINX with WebSocket / long executions
n8n’s editor streams execution updates. Buffering or short timeouts break the UI.
server {
listen 443 ssl http2;
server_name n8n.example.com;
ssl_certificate /etc/letsencrypt/live/n8n.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
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_buffering off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
Keep secrets in env files outside git; rotate credentials after first deploy.
Useful n8n env flags
N8N_HOST,N8N_PROTOCOL=https,WEBHOOK_URLEXECUTIONS_DATA_PRUNE=trueand retention limitsN8N_ENCRYPTION_KEY(set once, back it up)
Backups
Dump Postgres on a schedule (cron + pg_dump) to object storage. Also back up the n8n volume if you store binary data locally.