Heroku killed its free tier and bumped the ground. Vercel fees per seat and occasions out long-running jobs. Render and Railway scale worth with visitors.
Open the latest invoice out of your internet hosting supplier. The Node app, a Postgres database, and a Redis cache. Three line objects, three units of overage warnings, one frantic Slack thread the day advertising lastly launches a marketing campaign.
That invoice is why a variety of groups are taking one other have a look at the VPS. Node.js itself doesn’t care the place it runs. The one factor serverless was defending you from was discovering out what occurs after ‘npm begin.’
Let’s have a look at a production-setup sample for Node.js on a Linux field you management. In the event you can SSH right into a field and browse a config file, by the tip, you’ll have a manufacturing stack you possibly can run for years on a few hours of upkeep a month.
When Does Working Node.js on a VPS Make Sense?
A VPS is the suitable dwelling for Node.js when you’ve gotten a long-lived course of, a stack you need to consolidate into one invoice, or a managed-runtime bill that’s outgrown the comfort.
Broadly talking, there are three good matches:
- Lengthy-lived processes: WebSocket servers, queue employees, cron schedulers, MCP servers. Something that has to keep working and listening. Most serverless platforms nonetheless optimize round short-lived execution and request lifecycles. A Node course of on a VPS simply sits there.
- Value consolidation: Node app, Postgres, Redis, plus a small construct employee all stay on the identical 4 GB field. One invoice line, not 4.
- Apps that outgrew PaaS: Perform timeouts in your lengthy PDF technology job. Per-seat pricing on a staff that lastly employed a fourth engineer. A Heroku bill climbing previous $60 a month for a workload that runs fantastic on a $15 VPS.
And there are three fallacious matches:
- Static websites and SSG content material: A Subsequent.js export, an Astro construct, a Gatsby weblog. Vercel’s free tier is the suitable instrument. A VPS is overkill.
- Sparse, event-driven workloads: AWS Lambda or Cloudflare Employees value pennies for a webhook that runs ten occasions a day. A VPS prices the identical whether or not the app is busy or asleep.
- Horizontally-scaled real-time apps: In case your WebSocket server must fan out to 100,000 concurrent connections, one VPS shouldn’t be the reply. That’s a Kubernetes cluster, a distributed edge infrastructure, or a managed real-time platform.
JavaScript is the most-used language within the 2025 Stack Overflow Developer Survey, and Node.js stays one of many default methods builders run JavaScript on the backend. That’s lots of people working Node someplace. This text is for the slice of them who’d be happier working it on a server they management.
I’ve watched groups transfer 4 manufacturing Node companies off Heroku onto a single 4 GB VPS, with the identical uptime, a 3rd of the invoice, and long-lived WebSockets that lastly labored with no workaround.
The migration is usually a day of ‘apt set up,’ a ‘pm2 begin,’ and a DNS change.
What VPS Specs Does Node.js Truly Want?
Node.js itself is light-weight. A minimal Categorical server can idle nicely below 100 MB of resident reminiscence. The “Node solely wants 1 GB” recommendation you’ll nonetheless discover on older blogs is technically true and virtually ineffective. By the point you’ve added Postgres, Redis, logs, and a deployment course of that isn’t held along with hope, you’re already pushing previous that on a quiet day.
Reasonable sizing for widespread workloads:
| Workload | RAM | vCPU | Storage | Notes |
|---|---|---|---|---|
| Small Categorical API, no DB on the field | 2 GB | 1-2 | 40 GB NVMe | Reasonable flooring for one manufacturing app |
| Node API + Postgres + Redis on one field | 4 GB | 2 | 80 GB NVMe | The candy spot; most groups land right here |
| SSR-heavy app (Subsequent.js, Nuxt, Remix) | 8 GB | 4 | 80 GB NVMe | SSR rendering and construct pipelines are the place the reminiscence goes |
| Actual-time/WebSocket app, reasonable scale | 8 GB | 4 | 80 GB NVMe | Each persistent connection consumes reminiscence |
A number of specifics to pin down earlier than you provision:
- NVMe storage issues greater than uncooked disk dimension: Fashionable Node apps contact 1000’s of small information throughout installs, builds, and startup. Gradual disks make dependency installs, chilly boots, and SSR rebuilds noticeably worse.
- KVM virtualization, not OpenVZ: Older OpenVZ-based plans share a kernel with the host, which might imply outdated kernel variations and occasional compatibility complications with newer runtimes. Most respected VPS suppliers are KVM-only now, nevertheless it’s nonetheless value checking.
- Swap area: Allow 1-2 GB of swap on smaller containers. Node’s V8 heap can swing arduous throughout rubbish assortment. With out swap, a transient spike kills the method. I’ve watched a 4 GB field OOM throughout a routine deploy as a result of somebody had disabled swap considering it was a Docker-era anachronism.
- Bandwidth: Most fashionable VPS plans embrace 1-4 TB of month-to-month bandwidth, sufficient for nearly every thing in need of video internet hosting. Self-Managed VPS plans embrace unmetered bandwidth, one fewer line on the capacity-planning spreadsheet.
A 4 GB VPS runs round $15 a month at market price. That’s 50 cents a day, or roughly one airport espresso each two weeks. In comparison with paying individually for app runtimes, managed Postgres, and Redis on a PaaS, the economics flip surprisingly quick.
Which Node.js Model Ought to You Set up?
Set up Node.js 24 (codename Krypton). It’s the present Lively LTS launch, promoted in October 2025 and supported by way of April 2028 based on the official Node.js launch schedule.
A variety of tutorials nonetheless level folks at Node 22. These guides haven’t been up to date. In the event you’re beginning a brand new deployment at present, pin your CI picture and your VPS to Node 24.x.
| Model | Codename | Standing | EOL |
|---|---|---|---|
| Node.js 26.x | (none) | Present | Promotes to LTS in late 2026 |
| Node.js 24.x | Krypton | Lively LTS | April 2028 |
| Node.js 22.x | Jod | Upkeep LTS | April 2027 |
| Node.js 20.x | Iron | Finish-of-life | | Reached EOL April 30, 2026. Don’t use. |
A number of guidelines of thumb:
- Don’t run Present (non-LTS) releases in manufacturing: Node 26 exists for testing future compatibility and new runtime options, not for the app your income will depend on.
- Node 22 is the fallback possibility if a important dependency nonetheless hasn’t caught up with Node 24 compatibility: Many of the ecosystem stabilized inside a number of months of the LTS promotion.
- Pin your Node model in all places: Your CI picture, Dockerfile, .nvmrc, and manufacturing VPS ought to all agree. “Works on my machine” will get costly quick as soon as native modules enter the chat.
🤔Contemplating Bun? It’s quicker on some workloads and genuinely spectacular, however the ecosystem remains to be smaller, and the manufacturing observe file is shorter than Node’s. For many groups, boring wins.
NodeSource, which maintains the apt and yum repositories many manufacturing groups set up Node from, highlights enhancements within the 24.x line, beginning with a more recent V8 engine. Node 24 additionally ships now-mature tooling like built-in node –watch and a secure native check runner (node: check), each of which stabilized within the 20–22 strains and carry ahead right here. None of it’s flashy. It simply removes somewhat operational friction each month.
How Do You Set up Node.js on a VPS?
You’ve gotten two life like set up paths. Decide primarily based on whether or not the server runs one Node app or a number of.
NodeSource for a Single-App Server
That is the only manufacturing path. One setup script and one apt set up get you the present Node 24 LTS line as a system bundle, and future safety updates move by way of regular bundle upgrades.
On Ubuntu or Debian:
curl -fsSL https://deb.nodesource.com/setup_24.x | bash -
apt set up -y nodejs
Confirm the set up:
node -v
npm -v
It is best to see a Node 24.x launch.
RHEL-family distro directions (yum/dnf) stay within the official NodeSource distributions repository.
nvm for Per-Venture Model Switching
nvm (Node Model Supervisor) installs Node into your house listing and lets totally different initiatives run totally different Node variations. Helpful when you host a number of apps on the identical server or don’t have sudo entry.
Run this as your app person, not root:
curl -o- https://uncooked.githubusercontent.com/nvm-sh/nvm/v0.40.5/set up.sh | bash
Reload your shell, then set up Node 24:
nvm set up 24
nvm use 24
nvm alias default 24
👉One vital rule: Don’t use sudo ‘npm set up -g’ for utility dependencies.
World installs are normally reserved for machine-level CLI instruments like pm2, typescript, or nodemon. Your app dependencies belong in bundle.json and ought to be put in from the mission listing with npm ci.
| NodeSource | nvm |
|---|---|
| One Node model per server | A number of Node variations per server |
| Put in system-wide, runs as any person | Put in per person |
Auto-updates with ‘apt’ |
Managed manually |
Requires sudo |
No sudo required |
In the event you’re not sure, begin with NodeSource. Most single-purpose manufacturing servers don’t want per-project Node model switching.
👉DreamHost Self-Managed VPS customers: The Node app obtainable at provisioning ships with Node 22 LTS — nonetheless supported by way of April 2027. To run Node 24, use the NodeSource or nvm steps above after provisioning.
Ought to You Use PM2 or systemd to Hold Your App Working?
Both one works. The sincere reply is whichever your staff is snug with. PM2 is the developer-friendly path. systemd is the Unix-native path. Each resolve the identical three issues: restart on crash, begin at boot, and swish shutdown on ‘SIGTERM.’
In the event you’re beginning contemporary, right here’s tips on how to decide:
| PM2 | systemd | |
|---|---|---|
| Setup time | 3 minutes | 10 minutes |
| Cluster mode (multi-core) | In-built | Not inbuilt (begin N items) |
| Log rotation | Module: ‘pm2-logrotate’ |
In-built by way of ‘journalctl’ |
| Zero-downtime reload | ‘pm2 reload’ |
Normally dealt with manually with rolling restarts or a number of items |
| Reminiscence overhead (daemon) | Small daemon overhead | None (no further daemon) |
| Greatest for | Single-box, JS-shop, quick iteration | Multi-app containers, ops-team consolation |
The PM2 fast begin is precisely that, fast:
npm set up -g pm2
pm2 begin app.js --name api
pm2 startup # prints the systemd startup command to run
pm2 save # saves the present course of record
PM2 then turns into the one factor you discuss to: ‘pm2 logs,’ ‘pm2 reload api,’ ‘pm2 monit.’
👉Additionally value realizing: ‘pm2 startup’ writes a systemd unit, so the PM2 setup really makes use of systemd below the hood.
A minimal systemd unit for direct Node administration at ‘/and many others/systemd/system/api.service’:
[Unit]
Description=My Node API
After=community.goal
[Service]
Sort=easy
Consumer=app
WorkingDirectory=/var/www/api
ExecStart=/usr/bin/node server.js
Restart=on-failure
RestartSec=5
Surroundings=NODE_ENV=manufacturing
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.goal
Then ‘systemctl allow --now api.’ Logs stay in ‘journalctl -u api -f.’
In the event you’re already working PM2 and it’s working, don’t migrate to systemd simply because somebody on Hacker Information mentioned so. The PM2 daemon’s reminiscence isn’t why you’d migrate away from it.
Migrate when you’ve gotten an actual motive, like working half a dozen Node processes the place each megabyte counts, or delivery into an ops atmosphere the place each different service is a systemd unit, and PM2 stands out because the odd one.
How Do You Put NGINX (or Caddy) in Entrance of Your Node App?

You need a reverse proxy in entrance of Node for 5 causes: HTTPS termination, gzip/brotli compression, static asset serving, working a number of apps on the identical field, and simpler price limiting. Node can do all of those. NGINX and Caddy do them higher, and so they don’t take your occasion loop down when one thing misbehaves.
Decide NGINX if anybody in your staff already is aware of it. Decide Caddy if you need HTTPS in three strains of config and also you’re fantastic with a smaller advanced-configuration ecosystem.
Minimal NGINX Config
Put this proxy block in /and many others/nginx/sites-available/api, symlink to sites-enabled, then nginx -t && systemctl reload nginx.
server {
pay attention 80;
server_name api.instance.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Improve $http_upgrade;
proxy_set_header Connection 'improve';
proxy_set_header Host $host;
proxy_set_header X-Actual-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}
The ‘Improve’ and ‘Connection’ headers are the WebSocket-support strains. NGINX’s personal docs name out that Improve is a hop-by-hop header, so it wants specific dealing with when proxying WebSocket visitors.
Go away them in in case your app makes use of WebSockets now, or would possibly later. Socket.IO, GraphQL subscriptions over WebSockets, and a shocking variety of “common” real-time options rely upon that improve handshake.
The only most typical manufacturing bug I see in Node setups is a Socket.IO server behind NGINX with out these two strains. Connections fail intermittently, devs blame Socket.IO, and the precise drawback is normally proxy config.
Minimal Caddyfile
The Caddy reverse proxy quickstart model of the identical factor:
api.instance.com {
reverse_proxy 127.0.0.1:3000
}
That’s the whole file. So long as the area factors to the server and ports 80/443 are reachable, Caddy provisions and renews HTTPS robotically. Caddy’s docs say automated HTTPS provisions TLS certificates for websites and retains them renewed; its reverse proxy quickstart additionally notes HTTPS is automated when Caddy is aware of the hostname.
Bind Node to localhost, Not 0.0.0.0
No matter proxy you decide, configure your Node app to pay attention on 127.0.0.1:3000, not 0.0.0.0:3000. The one factor that ought to face the general public web on a Node field is the proxy. Pair this with UFW, Ubuntu’s widespread firewall frontend, to disclaim every thing besides ports 22, 80, and 443.
ufw default deny incoming
ufw enable 22/tcp
ufw enable 80/tcp
ufw enable 443/tcp
ufw allow
If SSH runs on a customized port, enable that port earlier than enabling UFW.
Bind to localhost from day one. The assembly the place somebody admits “the app was uncovered as a result of Node certain to 0.0.0.0” shouldn’t be a gathering you need to have.
How Do You Set Up HTTPS for Your Node.js App?
Use Let’s Encrypt. It’s free, automated, and trusted by each browser. There are two paths, relying on which proxy you picked.
NGINX + Certbot
Level an A file at your VPS IP and watch for DNS to propagate.
Set up Certbot:
apt set up certbot python3-certbot-nginx
Run:
certbot --nginx -d api.instance.com
Certbot updates your NGINX config and reloads the server robotically.
On fashionable Ubuntu releases, a systemd timer put in by the Certbot bundle handles renewal robotically.
Open https://api.instance.com and ensure the lock icon.
The official Certbot docs additionally cowl the snap-based set up path in case your distro bundle is outdated.
Caddy
Add the area to the Caddyfile (the instance above already has it), then restart Caddy. So long as the area resolves accurately and ports 80/443 are reachable, the certificates provisions robotically on first begin. There’s no Certbot.
Don’t terminate TLS in Node itself for manufacturing.
Node’s https module works completely nicely, however reverse proxies like NGINX and Caddy are purpose-built for TLS termination. They offer you OCSP stapling, fashionable cipher defaults, automated certificates renewal, HTTP/2 help, and — in Caddy’s case — HTTP/3 help out of the field.
May you deal with all of that immediately in Node? Positive. You’d simply be rebuilding infrastructure that your proxy already solves extraordinarily nicely.
What Does a Manufacturing-Prepared Node.js Setup Truly Look Like?
Eight issues chew folks in manufacturing. Most of them aren’t in set up tutorials as a result of they don’t match the “set up Node, run app” arc. They’re the distinction between an app that survives month two and one which doesn’t.
- NODE_ENV=manufacturing: The only most-missed step. In lots of Node frameworks and libraries, it disables dev-only habits and allows manufacturing optimizations. Categorical, for instance, caches compiled view templates and returns terser errors in manufacturing — its personal docs cite as much as a 3x efficiency enchancment. Set the ‘env var’ in all places.
- Sleek shutdown: When your VPS reboots or PM2 sends ‘SIGTERM,’ your app has a number of seconds to empty in-flight requests, shut database connections, and exit cleanly. Wire up a ‘course of.on(‘SIGTERM’, …)’ handler. PM2’s default shutdown timing will depend on configuration and atmosphere, so don’t assume you’ll at all times have a lot time to wash up.
- Log rotation: PM2’s ‘pm2-logrotate’ module handles this for PM2. The systemd journal handles it for direct systemd items. With out rotation, your logs eat the disk in 1 / 4 of the time you’d count on.
- .env self-discipline: By no means commit secrets and techniques, by no means log them. Use ‘dotenv’ for native dev. In manufacturing, set env vars by way of your systemd unit’s ‘Surroundings=’ or your PM2 ecosystem file. The day you ‘console.log(course of.env)’ by chance is the day you rotate each credential.
- A reverse proxy in entrance of Node: Bind Node to localhost; let NGINX or Caddy face the general public web.
- A firewall: UFW deny every thing besides 22, 80, 443. Transferring SSH away from port 22 gained’t cease a decided attacker, nevertheless it dramatically cuts down on automated brute-force noise and junk auth logs.
- Monitoring: A healthcheck endpoint your monitoring instrument hits each minute. PM2 has built-in fundamentals. For something severe, run Prometheus and Grafana, or use a hosted uptime service like Higher Stack or UptimeRobot. You need to know your app is down earlier than a buyer tells you.
Upkeep estimate for the stack above: one to 3 hours a month.
Apt updates, occasional dependency bumps, and a quarterly have a look at log quantity. That’s the commerce for the fee and management wins.
When Is a VPS the Flawed Alternative for Node.js?
A VPS is the fallacious name when your workload is constructed for one thing else. Be sincere about which facet you’re on earlier than you provision.
- Static websites and SSG content material: Subsequent.js export, Astro, Gatsby, and an Eleventy weblog. Platforms like Vercel, Netlify, or Cloudflare Pages offer you globally cached static internet hosting, Git-based deploys, and automated rebuilds out of the field. A VPS is normally pointless infrastructure for purely static content material.
- Sparse, event-driven workloads: Cloudflare Employees and AWS Lambda are cheap for webhooks working ten occasions per day.
- Actual-time apps that want 100,000+ concurrent connections: One VPS doesn’t horizontally scale. You’ll want orchestration (Kubernetes, ECS, Nomad) or a managed real-time platform like Ably or Pusher.
- Compliance-heavy regulated workloads: HIPAA, PCI-DSS Degree 1, FedRAMP. A managed PaaS with built-in compliance certifications saves audit ache. Self-hosting compliance on a VPS is a multi-quarter mission you in all probability don’t need.
- No Linux consolation — and no urge for food to construct it: Platforms like Render, Railway, and DigitalOcean App Platform sit someplace between uncooked VPS internet hosting and absolutely managed PaaS. Instruments like Dokploy add Heroku-style deployment workflows on prime of your personal VPS infrastructure. You continue to get a variety of the fee and management advantages with no need to grow to be deeply aware of iptables, systemd internals, or reverse-proxy debugging at 1 a.m.
There’s no disgrace in any of these solutions. The very best technical determination is the one which matches your workload.
Choosing Your Node Stack and Transferring In
Open that internet hosting bill yet another time.
You’re about to exchange a shocking quantity of it with a single VPS invoice.
👉The stack: Ubuntu 24.04 LTS, Node 24, PM2 (or systemd), NGINX (or Caddy), Let’s Encrypt by way of Certbot (or Caddy’s built-in).
Spin up the smallest VPS plan that hits the RAM you sized for, set up Node, run your app on ‘127.0.0.1,’ level NGINX at it, and swap your DNS.
If the app survives a deploy, a reboot, and an in a single day run with out drama, you’re many of the method there.
The remaining is upkeep. An hour or two a month, the occasional ‘apt improve’ window, a quarterly dependency bump. That’s the deal you made whenever you traded a per-seat bill for a flat one, and DreamHost’s Self-Managed VPS Stack 4 is the place you can begin.

Personal Your Total Stack. Apps, AI, Databases, and Extra.
Hold each credential and dialog on a server you management, with NVMe pace and unmetered bandwidth inbuilt.
Incessantly Requested Questions About Working Node.js on a VPS
Can I run Node.js on any VPS?
Most fashionable VPS plans run Node.js fantastic. Fashionable KVM-based VPS plans with a 64-bit Linux distro are the most secure default for present Node.js releases.
Older OpenVZ-based plans typically have kernel restrictions that break newer Node variations. In the event you’re choosing between suppliers, ask whether or not they’re KVM-based.
How a lot RAM does Node.js want on a VPS?
A minimal Categorical server idles nicely below 100 MB, however a practical manufacturing app with middleware, logging, and a connection pool sometimes runs within the 150-300 MB vary.
The life like minimal for one manufacturing app is 2 GB; the candy spot for a Node + Postgres + Redis stack is 4 GB. DreamHost’s Self-Managed VPS Stack 4 (4 GB) handles most manufacturing Node workloads. Bounce to Stack 8 (8 GB) for SSR-heavy or real-time apps.
What’s the present Node.js LTS model?
The present Lively LTS is Node.js 24.x (“Krypton”), promoted on October 28, 2025, and supported by way of April 2028. Node.js 22.x (“Jod”) is in Upkeep LTS by way of April 2027 if a dependency forces backward compatibility. Node.js 26 launched on Might 5, 2026, as Present and can be promoted to LTS in October 2026.
Most manufacturing groups keep on with LTS releases until they particularly want newer runtime options.
Do I want PM2 if I’ve systemd?
No, you don’t want each. PM2 and systemd resolve the identical drawback: holding your Node app working by way of crashes and reboots. Many Node-focused groups decide PM2 for built-in clustering, log administration, and reload tooling.
Groups already working systemd items for every thing else decide systemd.
Why put NGINX in entrance of Node.js?
NGINX (or Caddy) in entrance of Node.js centralizes TLS termination, compression, static asset serving, and price limiting in software program designed particularly for proxying and internet serving.
It additionally permits you to run a number of Node apps on the identical VPS with out port conflicts. In manufacturing, Node listens on localhost; NGINX faces the general public web.
Is Node.js on a VPS cheaper than Heroku or Vercel?
Sure, usually. A 4 GB VPS generally lands someplace within the $15-$25/month vary at market price and might consolidate app runtime, database, and cache prices which can be billed individually on many PaaS platforms.
Vercel Professional pricing is seat-based, and serverless platforms nonetheless impose execution-duration limits relying on runtime and plan.
The commerce is that you simply deal with operations your self, about one to 3 hours a month.
Can I run a number of Node apps on one VPS?
Sure, and it’s the commonest motive groups transfer from PaaS to a VPS. Run every app by itself inside port (3000, 3001, 3002) and route visitors with NGINX server blocks by hostname. PM2 manages all of them as separate processes; systemd makes use of one unit file per app.
A 4 GB VPS can usually deal with a number of light-weight Node companies alongside a small database workload.
Can I run Node.js on DreamHost shared internet hosting?
No. Node.js wants persistent processes, root-level bundle installs, and direct port binding, none of which shared internet hosting gives. DreamHost’s Self-Managed VPS plans (Stack 4 and up) match Node workloads with full root entry, NVMe storage, and unmetered bandwidth.
Did you get pleasure from this text?










