Cited

Self-hosting n8n: two weeks in, and the bill in hours

n8n on a small VPS for a fortnight. Where self-hosting paid off, and the maintenance work the pricing comparison never mentions.

A woman using a laptop navigating a contemporary data center with mirrored servers.
Photo: Christina Morillo / Pexels

Part of Automation that survives a month

Every argument for self-hosting n8n is made the same way: a table with the cloud plan's monthly price in one column and a VPS's monthly price in the other, and the VPS number wins by a wide margin. It is a true comparison and a useless one, because it prices the thing that costs almost nothing — compute — and leaves out the thing that costs almost everything, which is the hours a person spends keeping the server alive. We ran n8n on a small VPS for a fortnight specifically to put a number on the part the pricing page never shows, and logged every hour spent on it alongside the workflows themselves.

The short version: the compute cost was trivial, exactly as the tables promise. The maintenance was not trivial, and one afternoon of it looked nothing like "set it up and forget it." Whether that trade is worth it turns out to hinge on one number — how many workflow runs you actually push through the thing each month — and we can now say roughly where that number sits.

The setup: an hour, mostly spent waiting

We rented a 2 vCPU, 4 GB VPS running Ubuntu 24.04, the smallest instance the provider would sell with a dedicated IP, for a little under $6 a month. n8n's own Docker Compose template — Postgres, n8n, and Caddy for the reverse proxy and certificate — brought the stack up in about fifteen minutes of actual typing: clone the template, fill in the environment file with a domain and an encryption key, docker compose up -d. The rest of the hour was DNS propagating and Caddy waiting for Let's Encrypt to issue a certificate, which is dead time you cannot compress by working faster.

First working workflow — the same "intake" test we ran across Zapier, Make and n8n for the platform comparison, a form submission that creates a CRM contact, posts to Slack and sends an acknowledgement email — was saved and executing successfully forty minutes after the certificate landed. Call it ninety minutes from a blank server to a working automation, which is slower than clicking "sign up" on the hosted version but not by a margin that should scare anyone off on its own. The setup was never the argument against self-hosting. What follows is.

The maintenance log

Day 1–3. Nothing. The intake and digest workflows ran on schedule, the run history filled in as expected, no attention required. This is the stretch that makes self-hosting look free, and it is also the stretch every glowing forum post about it is written from.

Day 4, roughly forty minutes. We pointed the sync workflow — the paginated, rate-limited one from the platform comparison — at real data volume for the first time, and it ran into the same lesson n8n taught us the first time around: a node was returning an array and the next node down the line was firing once per item instead of once per batch, which is correct n8n behaviour and not a bug, but it meant redesigning one branch of the workflow rather than patching it.

Day 7, about two and a half hours, and the one that matters. n8n ships frequent releases, and we took a minor version upgrade mid-week rather than waiting, on the reasoning that trailing further behind only makes the eventual jump larger. The upgrade itself was one command. What it broke was a Function node in the attachments workflow that depended on a package version pinned inside the old image; the new image resolved a different minor version of the same package, and a method call that used to return a string started returning a Promise. Nothing in the changelog flagged it as a breaking change, because from n8n's side it was not one — it was a transitive dependency shifting under us. Finding it took about forty minutes of reading node output line by line. Fixing it took five. The other two hours went on doing what we should have done before touching the upgrade button at all: pinning the image to a specific tag, writing down the current working version, and building a habit of testing the upgrade against a cloned instance before applying it to the one doing real work. That habit is now permanent, and it is exactly the kind of cost a monthly-price comparison has no column for.

Day 9, twenty minutes. Disk usage alert, because n8n retains full execution data — every node's input and output, on every run — by default, and nobody had set a pruning policy. This is the same debugging strength we praised in the platform comparison, that you can open any past execution and see exactly what a node received, cutting both ways: it is also the reason the database grows without limit until you tell it not to. Setting a data-retention window fixed it in minutes once we noticed it, which is the point — on n8n Cloud this is handled for you and invisible; self-hosted, it is a setting you have to know exists.

Day 11, forty-five minutes. We tested backups, deliberately, rather than trusting that the nightly pg_dump cron job we'd set up on day one was actually producing a usable file. It was producing a file. It was not, on the first attempt, a file that restored cleanly — the dump ran while a workflow was mid-execution and captured a table in a state Postgres's own restore process rejected. Moving the dump to a quiet hour and adding a pg_isready check before it fired solved it, and the second restore worked. This is the single most important thing in this log: an untested backup is not a backup, it is an assumption, and the only way to know which one you have is to actually run the restore.

Total across the fortnight: a little over four hours of unplanned maintenance, against roughly ninety minutes of setup and near-zero hours in the quiet stretches. Two weeks is not long enough to see a major version jump or a real disk failure, so this number is a floor, not an average — but it is a real floor, logged as it happened rather than estimated afterward.

Where the trade genuinely wins

Three things about self-hosting held up under real use, and none of them are the sticker price.

No execution ceiling. Every hosted automation platform, n8n's own cloud tier included, prices around a run allowance of some kind. Self-hosted, the workflow that fires on every webhook delivery and the one that polls every sixty seconds cost the same: server load, not billed events. For the sync workflow, which by design runs constantly and paginates through everything on every pass, this is the difference between a workflow you build freely and one you have to budget.

Data stays on infrastructure you control. For workflows touching anything with a confidentiality requirement — health data, financial records, anything under a contract that names where processing happens — routing every payload through a third party's servers is a question someone eventually has to answer in a security review. Self-hosted, the answer is "our own VPS, in a region we chose," which is a much shorter conversation.

Custom code without limits. n8n's Function and Code nodes run arbitrary JavaScript or Python on the hosted version too, but self-hosted removes the sandboxing and package restrictions that a shared multi-tenant environment has to enforce for everyone else's safety. If a workflow needs an obscure npm package, a compiled binary called via a shell step, or a genuinely unusual data transform, self-hosting is where that becomes simple instead of a support ticket.

The threshold, priced honestly

Here is the trade stated as an equation rather than a feeling: self-hosting wins once the monthly maintenance hours, multiplied by what an hour of your time is actually worth, cost less than the hosted plan you would otherwise be paying for. That is not a number we can hand you, because both sides of it are yours to fill in — n8n Cloud's plan prices move and we would rather leave the blank than stale-quote one, and what an hour of your own or your team's time costs is not something we can know from here. Prices checked August 2026; check the current hosted-plan figure against your own hourly rate before deciding, because the arithmetic genuinely does flip depending on both.

What we can say from the log itself is where the volume needs to sit for the trade to make sense at all. Four hours of maintenance for a fortnight running four workflows at low-to-moderate volume is a real tax on a small setup — noticeable, not catastrophic. Scale those same four workflows to the run counts that make n8n the right platform in the first place — hundreds of executions a day, list processing on every run — and the maintenance hours barely move while the hosted plan's bill, priced per execution, keeps climbing. The four hours we logged do not scale with run volume; they scale with workflow count and complexity, which is the whole reason the equation tips in self-hosting's favor above a threshold and against it below one. Below a few dozen runs a day, the hosted plan is very likely still cheaper once you honestly price your own time. Above a few hundred, the VPS bill stays roughly flat while the metered alternative does not, and that is where self-hosting starts paying for itself rather than merely feeling cheaper.

Who should not do this

If nobody on the team already owns a server — patches it, gets paged when it falls over, has opinions about backup verification — self-hosting n8n is not a cost saving. It is a second, unpaid job wearing the outfit of a cost saving, and the four hours in this log were spent by someone who already knew what a pg_isready check was for. For anyone starting from zero on that front, the learning curve is itself the maintenance cost, and it front-loads onto exactly the weeks when a broken workflow is most likely to go unnoticed. The general shape of that risk — the gap between an automation working and someone finding out when it stops — is the whole subject of what makes an automation still work a month later, and self-hosting does not remove that risk; it just moves who is responsible for closing it. If your workflows also lean on the newer agent-style nodes rather than fixed logic, the maintenance profile shifts again, which is its own piece on running AI agents inside automation tools.

The honest recommendation is a volume test, not a philosophy. Log your actual runs for two weeks on whatever you are using now. If the number is in the hundreds a day and climbing, rent the VPS and budget the hours we just described — they are real, but they are smaller than the subscription you will stop paying. If the number is in the dozens, leave it hosted and spend the four hours on something else; the pricing table you started from was right about the compute and wrong about nothing else, which is precisely the problem.

Questions people ask

Is self-hosting n8n actually free?
The software and the compute are close to free — a small VPS runs a few dollars a month. What is not free is your time: upgrades, a broken node after a version bump, and building backups you have actually tested, which is where the real cost of self-hosting lives.
How long does it take to get n8n running on a VPS?
With Docker Compose and a template, under an hour from a blank server to a saved workflow, most of which is waiting for DNS and a certificate to issue rather than configuration.
What breaks when you self-host n8n instead of using the cloud version?
Nothing structural — the editor and the node library are identical. What changes is who owns the parts n8n Cloud used to handle invisibly: version upgrades, database backups, queue mode if you scale past a single instance, and the alerting that tells you when any of that has quietly stopped working.
Does self-hosting n8n remove all run limits?
Yes — there is no execution cap and no per-task billing once it is your own server, which is the entire financial argument for doing it. The cost moves from "per run" to "per hour of your time," and that trade only pays off above a certain volume.

Cited — We use a tool for a fortnight before we write a word about it, and we say where every number came from.