Automation
Zapier to n8n: cutting a €400 bill in one Tuesday afternoon
It's Tuesday, 14:00. The CFO forwards us a €412.50 Zapier invoice. By Friday, the workflows run on a €4.51 Hetzner box and the seat is cancelled.

The invoice that started it
It's Tuesday, 14:00. The CFO of a 22-person performance marketing agency in Utrecht forwards us a Zapier invoice. €412.50. It's the sixth one in a row above four hundred. Last March the same plan ran them €189. They onboarded a new ad client in May, two more in autumn, and the bill walked itself up the ladder. The Zaps run lead intake from three Meta ad accounts, invoice chasing in Stripe, deal-stage Slack pings from HubSpot, a Monday morning campaign digest, and forty-something smaller things that nobody on the current team wrote.
By 17:30 the same afternoon the highest-traffic flows are running in parallel on a fresh n8n box. By Friday the Zapier seat is downgraded to free. Total engineering time on our side: one afternoon and a Wednesday morning check-in. This is the playbook.
Why the Zapier bill grew
The mechanics are not a mystery. Zapier charges per task. A task is one successful action inside a Zap. Multi-step Zaps multiply. A single lead from Meta hits Slack (1), creates a HubSpot contact (2), adds it to a sequence (3), pings the AE (4), writes a row to a Google Sheet (5). One lead, five tasks. Forty leads a day across three ad accounts. Add the invoice-chase loop (Stripe webhook, check overdue, email, log, update status) and the count compounds. Their bill broke down to roughly 78,000 tasks a month, sitting on the Team plan.
Zapier's published pricing makes this transparent enough. The product is fine. The price curve is the cost of convenience: somebody else hosts the engine, somebody else swallows the egress, and that somebody else needs a margin. The moment your business outgrows the lower tiers, the curve gets steep.
What n8n actually is
n8n is a workflow automation tool with the same node-graph idea as Zapier. You drag triggers and actions onto a canvas, connect them with arrows, and ship. The difference: it's self-hostable under a fair-code license, and you pay the runtime cost, not a per-task tax. On a small VPS it runs whatever volume your VPS can handle. For this client, that was a €4.51/month Hetzner CX22.
It is not a drop-in replacement. The node catalogue is smaller. Some Zapier-native integrations don't exist, and you build them with the HTTP Request node, which is fine if you're comfortable reading API docs. The UI is less hand-holding. The community is sharp but you will end up in their GitHub issues at some point. It is also faster, more honest about what is happening on each step, and substantially better at debugging multi-step flows.
The Tuesday afternoon, in order
We block the calendar 13:00 to 18:00. One operator from the client (the person who actually wrote half the Zaps), one engineer from our side. Coffee. A second monitor.
Step 1: inventory
Before touching anything, export the Zap list. Zapier's UI shows it, but the cleanest dump is in the Zap History view. We catalogued 56 Zaps. About 18 of them hadn't fired in 90+ days. Six were duplicates of other Zaps that the original author forgot to delete. We marked 24 as in scope for migration. The rest got archived without ceremony.
Step 2: provision n8n
A small Hetzner VPS, Ubuntu 22.04, Docker, n8n in a single container behind Caddy for TLS. Total provisioning time was about 25 minutes, most of which is waiting on a DNS record to propagate.
docker run -d --restart unless-stopped \
--name n8n \
-p 127.0.0.1:5678:5678 \
-e N8N_HOST=flow.client.tld \
-e N8N_PROTOCOL=https \
-e WEBHOOK_URL=https://flow.client.tld/ \
-e N8N_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
-v /opt/n8n:/home/node/.n8n \
docker.n8n.io/n8nio/n8nCaddy in front handles certificates with one block:
flow.client.tld {
reverse_proxy 127.0.0.1:5678
}Save the encryption key in 1Password before you do anything else. If you lose it, your stored credentials are unrecoverable.
Step 3: rebuild the highest-traffic Zaps first
We sorted the in-scope Zaps by task count. The top three accounted for 71% of monthly tasks. We rebuilt those first, by hand, while the original Zapier versions kept running live. The lead-intake flow took 35 minutes. The invoice-chase loop, 50. The campaign digest, 40.
n8n's HTTP Request node covers anything you can't find a native node for. Meta Lead Ads, for example, needed a manual webhook setup, but it's the same webhook URL pattern Meta wants from any endpoint. HubSpot has a maintained node. Stripe has a maintained node. Slack has a maintained node. The 24 in-scope Zaps mapped onto 19 n8n workflows because a few of them collapsed into shared sub-workflows once we could actually see them side by side.
Step 4: parallel-run for 48 hours
We don't cut over immediately. For two days the new flows write to a staging Slack channel and a HubSpot test pipeline. We compare counts to the live Zapier output at the end of each day. On day two, all twelve high-traffic flows match within ±1 event. The mismatches are timezone edge cases at midnight UTC, which we patch.
Step 5: cut over by webhook
The only flows that need real cut-over are the ones with inbound webhooks (Meta, Stripe, calendar). Update the webhook URL at the source, watch the n8n executions tab for the first three or four real events, confirm the payload parses correctly, move on. The Zapier Zap stays on for another 24 hours as a safety net.
Step 6: archive Zapier
By Wednesday afternoon, every in-scope Zap is duplicated in n8n and verified. By Friday, the Zapier account is downgraded to free. The seat gets cancelled at the renewal date. Nobody on the team notices anything different in their Slack channels, which is the highest compliment a migration can earn.
What actually broke
Three things, in order of pain:
- The Stripe-to-HubSpot invoice loop double-fired on the first morning. n8n's default behaviour for the Stripe Trigger node is to refire on workflow restart unless you store a cursor. We added a Set Workflow Static Data step to track the last processed invoice ID. Five-minute fix once we read the relevant docs page.
- A Google Sheets node hit the per-user rate limit on day three. The agency's automation account was making four writes per second during the morning batch. We swapped to batch updates (one write per 60 rows) and the issue disappeared.
- The campaign digest email looked different in Outlook. Zapier's email-by-Zapier action wraps content in some opinionated HTML. We were sending raw HTML through n8n's Send Email node. Took twenty minutes to add a basic inline-styles wrapper. The new version actually looks better.
Self-hosting means you own uptime. If your n8n box dies at 3am, your invoice chases die with it. Set up basic monitoring (Uptime Kuma, healthchecks.io, or a simple cron-curl) before you cancel Zapier.
Watching the new system
Self-hosting trades a vendor's status page for your own dashboard. We installed Uptime Kuma on the same Hetzner box (it's a 50 MB Docker container) and pointed it at three things: the n8n web UI, the Caddy reverse proxy, and a synthetic workflow that fires every five minutes and writes to a private Slack channel only when it fails. The total maintenance burden since migration is one weekly check that nothing in Uptime Kuma went red overnight.
We also turned on n8n's built-in execution logs. The free retention is 7 days, which is plenty for an agency-sized workload. If something looks wrong, you open the Executions tab, find the failed run, see the exact node and payload, and patch. Zapier's task history is fine, but the depth of debugging in n8n is in another league: you can re-run individual nodes with edited input, which compresses a 20-minute "what was the exact payload" loop into about 90 seconds.
The numbers, six months in
We migrated on a Tuesday in early December. By June the picture is:
- Zapier bill: €0 (free tier, used only for the two Zaps we couldn't be bothered to migrate)
- Hetzner VPS: €4.51/month
- Hetzner snapshots and storage: €1.20/month
- Engineering time spent maintaining the n8n box since December: roughly 4 hours total, mostly upgrading n8n versions and adding two new flows the agency dreamed up later
Annualised, the client went from €4,950 to €69 in tooling spend, against the afternoon of engineering time we billed at our standard rate. Payback was about six weeks. After that, pure margin recovered, on a line item that had been quietly compounding for a year.
When you should not do this
The migration math doesn't work for everyone. Skip n8n if:
- Your Zapier bill is under €50/month. The cost of an engineer's afternoon plus your VPS will eat any savings for years.
- Nobody on your team is comfortable reading API documentation. Self-hosted tools require a human who can. If you don't have one, the cost of one consulting engagement per quarter to fix flows will quietly cost more than Zapier did.
- You rely heavily on Zapier's AI actions, paths, or formatter quirks. n8n has equivalents but they're shaped differently. Plan for a full rebuild, not a copy.
- You need SOC 2 compliance on the automation layer. n8n offers this on their cloud plan, but it costs more than Zapier. Self-hosted means you're the one doing the audit work.
For everyone else (the agencies, the e-commerce ops teams, the B2B SaaS doing high-volume lead handling), the math turns brutal in Zapier's disfavour above roughly €200/month in task spend. The break-even point arrives faster than most ops leads expect.
The smallest thing you could do today
Open your Zapier dashboard. Sort Zaps by task usage, descending. If the top three Zaps account for more than half your monthly tasks, those three are your migration target. Don't rebuild the long tail. Just move the heavy ones and watch the bill collapse.
When we built this automation backbone for the Utrecht agency, the thing we ran into was the Stripe webhook dedup, and we solved it with n8n's static workflow data and a fifteen-line Function node. If you're staring at a similar bill and an automation stack that grew organically, that's the kind of process automation we rewrite on the right substrate and hand back, working, on a Friday.
Key takeaway
Above roughly €200/month in Zapier tasks, a self-hosted n8n instance pays back in six weeks and an afternoon of engineering time.
FAQ
Is n8n really free?
The self-hosted Community edition is free under a fair-code license. You pay for the VPS that runs it, which is usually a few euros a month. n8n Cloud is paid and has tiered pricing similar to Zapier.
How long does a typical Zapier to n8n migration take?
For 20 to 30 active Zaps with mostly mainstream integrations, plan one afternoon to rebuild the heavy flows, 48 hours of parallel-running, and a Friday cut-over. Long tails of rarely-used Zaps usually get archived.
What breaks most often during the migration?
Webhook deduplication (n8n needs explicit cursor state for some triggers), Google Sheets rate limits if you write per-row, and email HTML rendering. All three are 15-minute fixes once you spot them.
Do I need to know how to code to use n8n?
Not for most flows. You do need to be comfortable reading API documentation when no native node exists and you have to use the HTTP Request node. If nobody on the team can read API docs, stay on Zapier.
What about SOC 2 or GDPR compliance?
Self-hosting puts the audit burden on you. GDPR is straightforward if your VPS is in the EU (Hetzner Falkenstein or Helsinki). SOC 2 on the automation layer is easier on n8n Cloud Enterprise than on a self-hosted box.