VPS for Node.js and Python: server sizing and deployment design
A reliable application server needs more than enough RAM to start. Plan processes, reverse proxy, database, deployment rollback, logs and backups before choosing a plan.

How much CPU, RAM and storage
| Scenario | Starting point | Watch |
|---|---|---|
| Telegram bot or webhook | 1 vCPU, 1–2 GB RAM | Peak queue and external APIs |
| Small API without local DB | 2 vCPU, 2 GB RAM | Latency, processes and connections |
| SSR site with PostgreSQL | 2–4 vCPU, 4–8 GB RAM | Database memory, builds and cache |
| Media and background jobs | 4+ vCPU, 8+ GB RAM | CPU time, storage and queue |
Build steps can consume more memory than normal traffic. Keep 20–30% operating headroom and monitor process RSS, swap, I/O wait and p95 response time.
A sound single-VPS architecture
- A reverse proxy terminates TLS on ports 80 and 443.
- The application runs as a dedicated non-root user.
- A process manager restarts failed workers.
- Secrets arrive through protected runtime configuration.
- Structured logs rotate before filling storage.
- External monitoring checks availability and certificate expiry.
- Database and user files are backed up outside the VPS.
For Node.js, systemd, PM2 or containers can supervise processes. Python web apps commonly use Gunicorn or Uvicorn behind Nginx. The choice matters less than clear ownership, health checks, bounded resources and a reproducible configuration.
Manage Node.js and Python versions deliberately
Pin an actively supported runtime version and dependencies with lock files. Avoid installing production runtimes through an administrator's interactive version manager if services cannot reproduce that environment. Build dependencies in CI or a controlled release directory, then deploy an immutable artefact.
Use a separate virtual environment for each Python project. Do not share a global node_modules tree. Record required system libraries and test upgrades before support ends.
Reliable deployment and quick rollback
Create versioned release directories or immutable container images. Upload the new release, install dependencies, run migrations with a documented compatibility plan, switch the active symlink or service, and perform smoke tests. Keep the previous release until the new one is proven.
Avoid building large frontend bundles on a small production VPS. CI can build once and publish the exact artefact that was tested. Database migrations should remain compatible with both old and new application code during a rolling change.
Local or managed database
A local database is economical and has low latency, but competes with the application for RAM, CPU and disk. A managed database adds network latency and cost while providing backups and operational separation. Split services when measurements, independent scaling or availability requirements justify it.
Find the real performance limit
| Symptom | Likely cause | First step |
|---|---|---|
| CPU stays at 100% | Blocking work or too few cores | Profile and move background jobs |
| OOM kills | Leak or too many workers | Inspect RSS and memory profile |
| High I/O wait | Database, logs or slow storage | Measure queries and consider NVMe |
| Low load but slow response | External API or database lock | Add distributed timings and timeouts |
Frequently asked questions
Which is better, Node.js or Python?
Choose by libraries, team experience and workload. Database design and operations usually matter more than the language.
Do I need Docker?
No. systemd and virtual environments are reliable too. Docker helps make environments portable when the team understands images, networks and persistent data.
Can several projects share one VPS?
Yes, with separate users or containers, limits, domains and backups. The physical host remains a shared failure point.
When should servers be separated?
When services compete for resources, must scale independently or one-node downtime is no longer acceptable.
Related: running Docker safely on a VPS.
