The signs your n8n VPS is undersized are pretty consistent: the container restarts on its own with exit code 137 in the logs, executions hang at "running" and never finish, webhooks start returning 504s, and the editor needs ten seconds to open an executions list that used to appear instantly. Memory runs out first in almost every case, usually because binary data and execution history sit in RAM while Postgres and Redis compete for the same couple of gigabytes. A 1 GB box will keep a quiet instance alive, 2 GB is a realistic floor once real workflows are running, and anything doing file processing, AI calls, or queue mode with workers wants 4 GB to 8 GB.
If your load average sits above your vCPU count and swap never empties, the server is the bottleneck, not your workflow logic.
Nine signs your n8n VPS is undersized, in the order they usually appear
These are the symptoms I check first, and they tend to arrive in a rough sequence. Memory pressure shows up before CPU, and CPU shows up before disk. Any two of these together usually means the box is out of headroom.
1. The container restarts by itself and the logs end at exit code 137
What makes this confusing is the timing. The crash rarely happens during the workflow that caused it. Memory creeps up across dozens of executions, then one modest run pushes the total past the limit and the kernel picks the biggest process, which is n8n.
Note: a container that restarts cleanly on a schedule is a different problem, usually a health check or a watchdog. Only exit code 137 (or an OOM entry in the kernel log) points at memory.
2. Executions sit at "running" and never return a result
An execution that shows "running" long after the workflow should have finished is often a process that died mid run. n8n never got the chance to write a final status, so the row stays open forever.
You'll see this in clusters. Five or six executions stuck at the same timestamp, then a gap, then normal runs again after the container came back up.
Check the age of those rows against your restart log. If the stuck executions line up with restarts, memory is the cause. If they're spread evenly and each one involves the same HTTP node, you're looking at a slow API rather than a small server.
3. Webhooks start timing out or returning 504s
n8n's main process handles the editor, the API, and incoming webhooks in a single Node.js process. When that process is busy running a heavy workflow, incoming webhook requests queue behind it, and the caller gives up first.
Stripe, GitHub, Twilio, and most other senders wait somewhere between 5 and 30 seconds before they call it a failure. A 504 from your reverse proxy is the same story from the other direction: nginx or Traefik asked n8n for a response and got nothing in time.
The pattern to look for is webhook failures clustered around the same minutes each hour, matching whatever scheduled workflow runs then. One process, two jobs, not enough CPU to do both.
4. The editor crawls, and the executions list is the worst part
A workflow list that takes eight seconds to render usually means the database is doing too much work on too little hardware. On the default SQLite setup, the execution history table grows without limit until you turn pruning on, and every page load asks that table for a summary.
I've seen SQLite files past 5 GB on servers where nobody had touched the data retention settings. Opening the executions tab on one of those pins the CPU at 100% for the duration of the query.
Two other tells: saving a workflow takes several seconds, and the editor throws intermittent 502s while you're mid edit. Both point at a database that has outgrown the box it's on.
5. Load average sits above your vCPU count
Run uptime or top and look at the three load numbers. On a 2 vCPU server, a five minute load average of 2.0 means the CPU is fully committed. Anything over that means work is waiting in line.
Sustained load of 4 or 5 on a 2 vCPU box is a clear signal, and it's one of the easiest signs your n8n VPS is undersized to confirm because it takes one command and no guesswork.
Watch for what pushes it there. Code nodes with heavy loops, large JSON transformations, image or PDF handling, and any node that parses big CSVs will all spike CPU. If the load only climbs during those runs and settles afterward, you may get away with tuning.
If it never comes back down, you need more cores.
6. Swap is permanently in use and I/O wait keeps climbing
Run free -h and look at the swap row. A little swap in use is normal. Swap that stays full while free memory hovers near zero means the kernel is constantly shuffling pages to disk to keep things alive.
Then run vmstat 1 5 and watch the si and so columns. Any steady nonzero numbers there mean active swapping, and on network-attached VPS storage that's slow enough to make every workflow feel broken.
The related number is %wa in top, which is CPU time spent waiting on disk. Double digit I/O wait on a server that isn't moving files around is a memory problem wearing a disk costume.
7. Disk space disappears without you uploading anything
n8n writes an execution record for every run, including the input and output data of each node, unless you tell it otherwise. Add Docker's own log files and a few old images and a 20 GB volume fills up faster than most people expect.
Check df -h first, then docker system df to see how much of it is Docker's. If /var/lib/docker/containers holds gigabytes of JSON logs, your log driver has no rotation set.
A full disk breaks n8n in an ugly way. Postgres refuses new writes, SQLite throws disk I/O errors, and executions fail with messages that have nothing to do with the actual cause. It's worth knowing how far back your snapshots reach before you start deleting things to free up room.
8. Small payloads are fine, but anything with a file takes the box down
By default n8n keeps binary data in memory while a workflow runs. Download a 40 MB attachment, pass it through two nodes, and you're holding multiple copies at once because each node's output gets stored separately.
That's why a workflow that handles 200 JSON records without complaint will kill a 2 GB server the moment it touches a PDF or a video file.
Switching N8N_DEFAULT_BINARY_DATA_MODE to filesystem moves that data to disk instead of RAM, which is the single biggest memory saving available to most self-hosted setups. Newer releases also support external object storage, so check the current options in the configuration reference for your version. If you're regularly moving large files around, our notes on sensible upload ceilings are worth a look too.
9. Steal time shows up in top
In top, the CPU line includes %st for steal time. That's CPU cycles your server asked for and didn't get because the physical host gave them to someone else.
Anything consistently above 5% means you're sharing a busy host. This is not something you can fix with configuration, and it's not strictly a sizing problem, though the two often travel together on the cheapest plans.
Note: steal time varies by provider and by host, so one bad reading during a backup window doesn't mean much. Sample it a few times across a day before you conclude anything.
How to confirm the server is the problem in about five minutes
Run these in order before you change a plan or a config value. Each one takes seconds and rules out a whole category of cause.
- Check memory with
free -h. Note how much is free, how much is cached, and whether swap is in use. - Check per-container usage with
docker stats --no-stream. Compare the n8n container's memory against its limit, and look at Postgres and Redis in the same output. - Check load with
uptimeand compare the five minute figure against your vCPU count withnproc. - Check disk with
df -h, thendocker system dfif the root volume is above 80%. - Look for kills with
journalctl -k --since "24 hours ago" | grep -i oom. Any hits here settle the question. - Read the last 200 lines of the container log with
docker logs --tail 200 n8nand note any repeated errors right before a restart. - Check the database size. For SQLite,
ls -lhon thedatabase.sqlitefile in your n8n data directory. For Postgres,SELECT pg_size_pretty(pg_database_size('n8n'));.
If steps 1, 2, and 5 come back clean and the only slow thing is one specific workflow, the server is fine and the workflow needs attention instead. Slow API responses, retry loops, and a Wait node doing exactly what it was told all look like server trouble from the outside. The same principle applies to any host: I go through a similar routine when tracking down a sluggish site rather than assuming the plan is too small.
How much RAM and CPU an n8n VPS actually needs
There's no single official number, because n8n's memory use depends almost entirely on what your workflows carry through them. The table below reflects what these setups need in practice, and it's a starting point rather than a guarantee.
| Setup | RAM | vCPU | Disk |
|---|---|---|---|
| Testing, SQLite, a handful of runs a day, no files | 1 to 2 GB | 1 | 20 GB |
| Production single instance, Postgres on the same box, dozens of active workflows | 4 GB | 2 | 50 GB |
| Files, AI nodes, large JSON, or queue mode with two workers | 8 GB | 4 | 80 to 100 GB |
| Multiple worker nodes, database on a separate server | 16 GB per node | 4 to 8 | 100 GB+ |
Two things shift these numbers more than execution volume does. The first is payload size, because a workflow moving 50 MB files needs several times the memory of one moving 50 KB of JSON at the same frequency. The second is whether Postgres and Redis share the box, which typically claims 500 MB to 1 GB before n8n starts.
Note: n8n's official documentation covers supported databases, environment variables, and scaling options for the version you're on, and those details change between releases. Check the n8n docs for current specifics rather than trusting a spec sheet from a blog post, including this one.
If you're weighing this against an entry-level shared plan, that decision has its own set of triggers, and we walked through them in a separate piece on outgrowing entry-level hosting. Short version for n8n specifically: shared hosting can't run it at all in any reliable way, so VPS is the floor and the only question is which size.
Fixes worth trying before you pay for a bigger plan
Some of these give back more headroom than a plan upgrade would, and they cost nothing. Work through them in this order.
Turn on execution pruning. EXECUTIONS_DATA_PRUNE=true enables it, EXECUTIONS_DATA_MAX_AGE sets how many hours of history to keep, and EXECUTIONS_DATA_PRUNE_MAX_COUNT caps the total row count. Defaults have shifted across versions, so set them explicitly instead of assuming. On a server that has never pruned, the first run can reclaim several gigabytes.
Stop saving data you don't need. EXECUTIONS_DATA_SAVE_ON_SUCCESS=none keeps failures for debugging while dropping the successful runs that make up most of your table. I keep progress saving off as well, since EXECUTIONS_DATA_SAVE_ON_PROGRESS=true writes to the database after every single node.
Move binary data to disk. Setting N8N_DEFAULT_BINARY_DATA_MODE=filesystem is the fix for sign 8 above. Give it a dedicated volume with room to breathe and let n8n's cleanup handle the rest.
Cap concurrency. N8N_CONCURRENCY_PRODUCTION_LIMIT limits how many production executions run at once. On a 2 GB server, a limit of 5 stops a burst of webhook calls from taking everything down. Executions above the cap wait their turn instead of failing.
Switch from SQLite to Postgres. SQLite is fine for a light instance and becomes the bottleneck once execution history grows. Postgres handles concurrent writes far better, and it's a requirement if you want queue mode later, since multiple n8n processes can't share a SQLite file.
Add swap as a stopgap. A 2 GB swap file on a 2 GB server prevents hard OOM kills and buys you time to plan properly. Performance while swapping is genuinely bad, so treat this as a bridge and nothing more.
Rotate Docker logs. Set max-size and max-file on the log driver in your compose file. Docker's documentation covers the logging options and resource limits, and setting an explicit memory limit on the container is worth doing so a runaway workflow doesn't take down Postgres alongside n8n.
Then consider queue mode. Setting EXECUTIONS_MODE=queue with Redis splits the work so the main process handles the editor and webhooks while separate worker processes run the executions. This is the real fix for signs 3 and 5, because it stops workflow runs from blocking incoming requests. It also needs more total RAM, not less, since you're running more processes.
Add it when you have the memory to spare, not as an escape from a 2 GB box.
Common mix-ups about undersized n8n servers
Mix-up: More RAM will make slow workflows run faster.
Reality: Most slow executions are waiting on someone else's API, not on your hardware. Check the per node timings in the execution view first, because a 30 second HTTP node stays 30 seconds on a 32 GB server.
Mix-up: n8n will spread work across all the vCPUs you give it.
Reality: The main n8n process is a single Node.js process and uses one core for JavaScript execution. Extra cores help the database and the OS, and they only help n8n directly once you're running workers in queue mode.
Mix-up: The 1 GB plan is fine because n8n idles at 300 MB.
Reality: Idle memory tells you almost nothing. What matters is peak use during your heaviest concurrent runs, and that can be five or six times the idle figure with a couple of large payloads in flight.
Mix-up: A restart every few days is just a quirk of self-hosting.
Reality: It's an OOM kill, and it silently drops any execution that was mid run. Documenting your own environment variables and limits as you change them makes this much easier to trace later, which is one reason keeping written records of your setup pays off on self-hosted tools.
What this means for your setup
If you found two or more of the nine signs, the honest answer is that tuning will only carry you so far. Pruning and filesystem binary data will pull a struggling 2 GB instance back to stability. Neither creates headroom for AI nodes, document processing, or a second worker.
The upgrade path most people want is 4 GB with 2 vCPUs for a single production instance, then 8 GB with 4 vCPUs once queue mode and workers enter the picture. Pick a provider that lets you resize without rebuilding, because n8n workloads grow in steps rather than smoothly, and the day you add one file-heavy workflow is the day your sizing assumptions change.
Worth checking before you commit: whether the plan includes snapshots, whether you can add a separate volume for binary data, and whether HTTPS on your webhook endpoints is handled for you or left to you. If you're standing the instance up on its own hostname, our guide on pointing a subdomain at a server covers that part, and the certificate side of things matters because most webhook senders refuse plain HTTP.
Check current Hostinger VPS plans and pricing
Frequently asked questions
How much RAM does n8n need on a VPS?
Plan on 2 GB minimum for anything you rely on, and 4 GB if Postgres runs on the same server. Workflows handling files, large JSON, or AI model calls want 8 GB, mostly because binary data sits in memory by default.
Can n8n run on a 1 GB VPS?
Yes, for testing and for a few light scheduled workflows with SQLite and no file handling. It will get killed by the out-of-memory killer as soon as you add real payloads or run a couple of workflows at once, so it's not a setup I'd point a production webhook at.
Does queue mode reduce memory use?
No, it increases total memory use because you're running a main process plus one or more workers. What it does is stop long executions from blocking the editor and incoming webhooks, which fixes the timeouts and 504s rather than the memory pressure.
Should I upgrade the VPS or move to n8n Cloud?
Upgrade the VPS if you want control over versions, data location, and unlimited executions at a fixed monthly cost. Cloud makes more sense if you'd rather not manage Postgres, Redis, backups, and updates yourself, since n8n Cloud plans are priced by execution volume and the maths changes fast at higher run counts.
Where to go from here
Run the seven checks above, apply pruning and filesystem binary data first, and give it a week. If the container still restarts or the load average stays above your core count, size up to 4 GB and 2 vCPUs and stop fighting it. You can see what Hostinger's VPS tiers cost right now and the coupon code hHostCouponHub applies at checkout if a current promotion is running.
This page contains affiliate links. If you purchase through the links on this page, we may earn a commission, at no extra cost to you.




