Self-Hosted n8n in Production: Real Costs vs Zapier & Make (2026)
How the billing models differ
| Platform | Unit billed | Implication |
|---|---|---|
| Zapier | Task (per action step) | Multi-step Zaps multiply cost fast |
| Make | Operation/credit | Loops multiply credits |
| n8n Cloud | Execution (full workflow run) | Steps inside one run = one execution |
| n8n self-hosted | Server cost only | Unlimited executions; you ops the box |
Example monthly cost at scale
Assume 10,000 workflow runs/month, average 5 steps each:
- Zapier: ~50,000 tasks → often $200–400+/mo on Team tiers
- Make: ~50,000 operations → $50–150/mo depending on plan
- n8n self-hosted on $12–24 VPS → ~$12–24/mo + your time
At low volume (<500 runs), all three can sit on free tiers — self-hosting is not worth the ops overhead.
Self-hosting is not free
Budget for:
- VPS ($6–30/mo) or homelab power
- Backups (restic/S3)
- SSL + reverse proxy (Caddy/Nginx)
- Upgrade testing when n8n releases breaking changes
- Monitoring when workflows fail at 2 a.m.
I run self-hosted n8n for content pipelines, SEO automation, and client integrations — the break-even vs Zapier happened around 2,000 executions/month.
When to choose each
- Zapier — fastest setup, largest app directory, low volume
- Make — visual complex flows, moderate volume
- n8n self-host — high volume, multi-step flows, data sovereignty
- n8n Cloud — n8n without ops, per-execution pricing
Production setup (docker-compose outline)
Typical stack on a $12–24/mo VPS (2 vCPU, 4GB RAM):
- Docker + docker-compose
- n8n + PostgreSQL (not SQLite at scale)
- Caddy or Nginx reverse proxy with Let’s Encrypt
- Daily restic backup to S3-compatible storage
- Uptime monitoring (Uptime Kuma or external ping)
First-time setup: 4–8 hours for someone comfortable with Linux. Ongoing: 1–3 hours/month for updates and failed workflow triage.
Five workflows we run in production
- Lead routing — form submit → CRM + Slack + email
- Content pipeline — draft notification → review webhook → publish hook
- SEO monitoring — rank drop alert → task in project tool
- Client reporting — GA4 API → Looker Studio refresh trigger
- Backup verification — nightly check → alert if stale
Export workflows as JSON for disaster recovery.
Break-even calculator
| Monthly executions | Zapier est. | Make est. | Self-hosted VPS |
|---|---|---|---|
| 500 | Free–$20 | Free–$10 | Overkill |
| 2,000 | $50–100 | $20–50 | ~$18 |
| 10,000 | $200–400 | $50–150 | ~$18–30 |
| 50,000 | $500+ | $200+ | ~$30–50 (+ ops time) |
Add $50–150/hour for your ops time when comparing.
Failure modes (honest)
- n8n upgrade breaks credential encryption → test in staging
- Webhook timeouts on cheap VPS → increase timeout, queue jobs
- OAuth token expiry on Google nodes → refresh automation
- No monitoring → silent failures for days
When NOT to self-host
- Team has zero Linux admin capacity
- Compliance requires vendor SOC2 and you cannot attest infra
- Volume under 1,000 runs/month
Architecture: production stack explained
Self-hosting is not “install and forget.” Here is the stack we run for Gurkha Technology client automation and internal SEO pipelines.
Internet → Cloudflare (DNS/proxy) → Caddy/Nginx (TLS) → n8n (Docker)
↘ PostgreSQL
Backups: restic → S3-compatible bucket (daily)
Monitoring: Uptime Kuma + webhook alert to Slack/WhatsApp
Why PostgreSQL, not SQLite
SQLite works for experiments. Production workflows with concurrent executions, webhook bursts, and 50+ active workflows corrupt or lock SQLite under load. PostgreSQL adds ~512MB RAM overhead — worth it.
VPS sizing guide
| Workload profile | vCPU | RAM | Disk | Est. USD/mo |
|---|---|---|---|---|
| Light (<2k runs/mo) | 1–2 | 2GB | 40GB | 6–12 |
| Agency default (2k–20k) | 2 | 4GB | 80GB | 12–24 |
| Heavy (20k+, many HTTP nodes) | 4 | 8GB | 160GB | 24–48 |
Providers we have used: Hetzner, DigitalOcean, Vultr — pick Kathmandu/Singapore region for lower latency to Nepali APIs where available.
docker-compose essentials
- Pin n8n image version — do not track
latestin production - Separate
.envfor secrets; never commit credentials - Set
N8N_ENCRYPTION_KEYbefore first run — loss means re-entering all credentials - Configure
WEBHOOK_URLto public HTTPS domain - Limit execution data retention (prune after 7–14 days) to control DB size
See GitHub Actions CI/CD for how we deploy static sites that receive n8n webhooks.
Detailed cost model (year 1)
| Cost line | Self-hosted n8n | Zapier (mid volume) | Make (mid volume) |
|---|---|---|---|
| Platform fee (annual) | $0 | $240 – $4,800 | $120 – $1,800 |
| VPS (annual) | $144 – $576 | — | — |
| Backup storage | $12 – $60 | Included | Included |
| Domain for webhooks | $0 – $15 | — | — |
| Setup labor (one-time) | 4–8 hrs | 1–2 hrs | 2–4 hrs |
| Ops labor (monthly) | 1–3 hrs | ~0 | ~0 |
Hidden Zapier tax: each extra step in a Zap is a billable task. A 5-step workflow at 10,000 runs = 50,000 tasks. n8n counts 10,000 executions.
Task math example
Scenario: Lead form → validate email → CRM create → Slack notify → Google Sheet log → conditional branch to assign owner (6 steps)
| Runs/mo | Zapier tasks | Make ops (approx.) | n8n executions |
|---|---|---|---|
| 1,000 | 6,000 | 6,000 | 1,000 |
| 5,000 | 30,000 | 30,000 | 5,000 |
| 20,000 | 120,000 | 120,000 | 20,000 |
At 20,000 runs, Zapier Team/Company tiers dominate TCO unless ops time is valued at zero.
Step-by-step self-host deployment
- Provision VPS — Ubuntu LTS, enable firewall (22, 80, 443 only)
- Install Docker + Compose
- Create PostgreSQL + n8n services in compose file
-
Configure Caddy automatic HTTPS for
n8n.yourdomain.com - Set encryption key + admin password — store in password manager
- Create non-admin users per client or per workflow group (RBAC)
- Import test workflow — HTTP webhook → Set node → Slack
- Configure backups — nightly DB dump + restic
- Set up monitoring — external ping every 5 min
- Document runbook — upgrade procedure, restore procedure
First production workflow should be low-risk (internal notification), not client-facing payment sync.
Workflow patterns for marketing agencies
Client lead routing
Webhook from website form → dedupe by email → HubSpot/Sheets CRM → assign by city → Slack channel → delay → email auto-reply
Why n8n: branching and error handling without per-branch task billing.
SEO rank drop alert
Scheduled cron → pull rank API → filter drops >3 positions → create Asana task → optional LLM summary for client email draft (human sends)
Connect to automated SEO pipeline and AI automation stack.
E-commerce order ops (Nepal)
WooCommerce webhook → WhatsApp template to warehouse → courier API → update Sheet → failed payment alert
Local wallet callbacks sometimes duplicate — idempotency node required.
Reporting automation
Monthly cron → GA4 Data API → populate Looker Studio source sheet → email account manager “report ready”
Cheaper than Supermetrics at scale; more setup than Zapier’s GA connector.
Security hardening checklist
- HTTPS only; HSTS via Cloudflare or Caddy
- Basic auth or SSO in front of n8n UI
- Separate credentials per client workflow where possible
- Webhook paths use unguessable tokens
- Disable unused nodes/community nodes you do not audit
- Patch VPS monthly; test n8n upgrades on staging clone first
- Backup restore tested quarterly (not just “backups exist”)
Upgrade and migration runbook
- Snapshot VPS
- Export all workflows JSON to Git
- Pull new n8n image on staging
- Run test workflows including OAuth (Google, Meta)
- Production upgrade in maintenance window
- Monitor error queue for 24 hours
OAuth tokens break most often — budget re-auth time for Google Sheets and Ads nodes.
n8n Cloud vs self-host vs Zapier (decision matrix)
| Criterion | Zapier | Make | n8n Cloud | n8n self-host |
|---|---|---|---|---|
| Time to first workflow | Minutes | Minutes | Minutes | Hours |
| Multi-step cost scaling | Poor | Moderate | Good | Excellent |
| Data residency control | Low | Low | Medium | High |
| Custom code (JS/Python) | Limited | Limited | Strong | Strong |
| Nepali SME budget fit | Low volume | Mid volume | Mid volume | High volume |
Honest ops time journal (sample month)
| Activity | Hours |
|---|---|
| Failed workflow triage | 1.5 |
| n8n patch + test | 0.5 |
| VPS security updates | 0.5 |
| New client workflow | 2.0 |
| Backup verify | 0.25 |
| Total | ~4.75 |
At NPR 2,000/hour equivalent, add NPR 9,500/mo to true TCO — still beats Zapier at 10k+ multi-step runs.
Community nodes vs core nodes
Community nodes extend n8n (scrapers, niche APIs) but add supply-chain risk:
- Audit GitHub repo activity before install
- Pin version; disable auto-update on community pack
- Prefer HTTP Request node + documented API over obscure community node
- For client data, default to core nodes only unless security-reviewed
High-availability (when clients depend on it)
Single VPS is fine for most agency automation. Consider HA when:
- Lead routing for NPR 500k+/month ad spend client
- Payment-adjacent workflows (inventory sync, not card data)
- SLA in contract with financial penalty
Pattern: primary VPS + warm standby + DB replication — doubles cost, rarely needed before 15+ retainer clients.
Comparison with Make for visual builders
Make excels when non-developers build flows. Our team uses:
- Make: one-off client automations, marketing ops staff can edit
- n8n self-host: high-volume, branching, code nodes, cost-sensitive
Document who owns each platform — client offboarding nightmare when automations live in personal Make accounts.
Legal and client contract notes
- State in MSA who hosts automation server
- Data processing: lead PII flows through n8n — secure VPS, NDPA awareness
- Export JSON on contract end — same as GA4/GTM ownership in pricing guide
Staging instance (non-optional at scale)
Run n8n-staging. subdomain on smaller VPS or same box with separate DB:
- Test OAuth reconnect after Google password policy change
- Clone production workflow before editing live lead router
- Upgrade n8n image here first
Cost: +$6–12/mo or shared resources — cheaper than one hour of missed leads.
Docker-compose reference (minimal production)
Conceptual structure — adapt paths and secrets:
services:
postgres:
image: postgres:15
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- pg_data:/var/lib/postgresql/data
n8n:
image: n8nio/n8n:1.72.0 # pin version
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
WEBHOOK_URL: https://n8n.example.com.np/
depends_on:
- postgres
ports:
- '127.0.0.1:5678:5678'
caddy:
image: caddy:2
ports:
- '443:443'
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
Run Postgres on same VPS until 20k+ executions/month; then consider managed DB.
Webhook reliability patterns
Nepali ISPs and mobile networks drop connections:
- Retry with exponential backoff on HTTP Request nodes
- Queue heavy jobs — split webhook ack from processing
- Idempotency key in header or body — store in Postgres
- Dead letter Slack channel for workflows that fail 3×
Wallet callbacks from eSewa/Khalti are the highest-stakes webhooks — log raw payload before parsing.
Monitoring and alerting stack
| Tool | Purpose | Cost |
|---|---|---|
| Uptime Kuma | HTTP ping n8n + public webhook | Free self-host |
| n8n error workflow | Slack on execution failed | Free |
| Grafana + Loki | Log aggregation at scale | Free–low |
| PagerDuty | Client SLA with on-call | Paid |
Minimum viable: Uptime Kuma + error workflow — 30 min setup.
Credential management
- One credential set per client for OAuth where possible
- Rotate after staff offboarding
- Never share production n8n login — use RBAC user per team member
- Store
.envin password manager, not Slack
Client billing for automation work
Agencies undercharge automation setup. Reference digital marketing pricing:
| Deliverable | NPR one-time |
|---|---|
| Lead router workflow | 15,000 – 30,000 |
| Report automation | 20,000 – 40,000 |
| E-commerce alert pack | 25,000 – 50,000 |
| Monthly monitoring retainer | 5,000 – 15,000/mo |
Explain ROI in hours saved — finance clients understand.
Zapier migration checklist
Moving client from Zapier to n8n:
- Export Zap list with step counts (task math)
- Rebuild top 3 Zaps by volume first
- Run parallel 2 weeks — compare outputs
- Cut Zapier subscription after validation
- Document JSON exports in client Git repo
Typical savings NPR 15,000–40,000/month equivalent at scale — see break-even table above.
Homelab vs cloud VPS
Homelab on NTC fiber saves USD but risks:
- Power cuts (UPS required)
- Dynamic IP (Cloudflare tunnel helps)
- No SLA for client contracts
Use homelab for personal automation; client production on VPS with backup.
n8n Cloud pricing snapshot (2026)
When self-host ops is not viable:
| n8n Cloud tier | Executions/mo | Approx USD | vs self-host |
|---|---|---|---|
| Starter | 2,500 | ~24 | Similar VPS cost, less ops |
| Pro | 10,000 | ~60 | Cheaper than Zapier tasks |
| Enterprise | Custom | Custom | SOC2, support |
Break-even: self-host wins above ~5k executions unless you bill ops time at zero.
Make.com vs n8n feature trade-offs
| Feature | Make | n8n self-host |
|---|---|---|
| Visual builder | Excellent | Good |
| Code nodes | Limited | JavaScript/Python strong |
| Self-host option | No | Yes |
| Nepal latency | EU/US servers | Choose APAC/SG VPS |
| Client handoff | Easy for non-devs | Needs technical handover doc |
We keep Make accounts for two legacy clients who edit own flows; everything new defaults n8n.
Execution data retention policy
n8n stores execution logs in Postgres — grows unbounded:
- Set
EXECUTIONS_DATA_MAX_AGE(e.g., 168 hours) - Prune success executions aggressively
- Keep error executions longer for debug
- Monitor disk weekly on small VPS
Disk full at Dashain campaign peak = missed leads — automate disk alert.
Integration with GitHub Actions CI/CD
Pattern: post-deploy webhook → n8n → Slack “site live” + IndexNow + cache purge request to Cloudflare API.
Same orchestrator handles marketing site and client static properties — one VPS, many webhooks.
Disaster recovery drill (annual)
- Restore Postgres backup to staging
- Import workflow JSON from Git
- Reconnect OAuth credentials (expect re-auth)
- Fire test webhook end-to-end
- Document minutes to recovery
Target RTO under 2 hours for agency SLA credibility.
Real workflow JSON export discipline
Every production workflow:
- Export JSON after change
- Commit to private Git with message
workflow: lead-router v1.3 - Tag release before n8n upgrade
- README in repo: credentials mapping (not secrets), owner, client
Client offboarding = Git handover + credential rotation checklist.
Scaling beyond single VPS
When executions exceed 50k/month:
- Split read-heavy workflows to second worker
- Move Postgres to managed service
- Consider n8n queue mode with Redis
- Rate-limit outbound API calls to avoid Google/Meta throttling
Most Nepali agencies never need this tier — single 4GB VPS handles 20k runs comfortably if DB pruned.
Cost comparison worksheet (copy for clients)
| Item | Zapier annual | n8n self-host annual |
|---|---|---|
| Platform | $2,400 | $0 |
| VPS | — | $216 |
| Backups | — | $36 |
| Setup (one-time) | $0 | $400 (8hr @ $50) |
| Ops (monthly × 12) | $0 | $600 (1hr @ $50) |
| Total year 1 | $2,400 | $1,252 |
At 10k multi-step runs Zapier often exceeds $3,600 — worksheet closes sales for automation upsell tied to agency stack.
Troubleshooting production incidents (runbook)
| Symptom | First action |
|---|---|
| All workflows failed | Check VPS disk, RAM, Docker daemon |
| Single workflow failed | Open execution log, test credential |
| Webhook 504 timeout | Increase proxy timeout, optimize nodes |
| Google node auth error | Reconnect OAuth in n8n credentials |
| Duplicate CRM rows | Add dedupe node on email field |
Keep runbook in Notion/Git — junior on-call should recover without calling you at midnight.
Zapier task reduction tactics (before migrating)
If client resists migration short-term:
- Combine multi-step Zaps into Code step (single task)
- Use Paths sparingly — each path branch may bill
- Filter early — drop noise before actions
- Schedule batch runs instead of per-row triggers
Still temporary — break-even table above shows when migration pays.
Observability: what to log
Minimum logging for production n8n:
- Workflow name + execution ID on failure
- Webhook payload hash (not full PII) for dedupe debug
- Outbound API status codes
- Execution duration — flag workflows >30s
Ship logs to Loki or even structured JSON files with logrotate — debugging without logs wastes more time than logging costs.


