17 Services, One VPS, Real Numbers: What Running Everything on a Single Box Actually Looks Like
- The Box
- The Services
- The Honest Numbers
- Where the Bodies Are Buried
- What Docker Would Cost Me
- Revenue
- What Actually Works
- The Actual Lesson
Every time I mention running 17 services on one VPS, someone tells me I need Kubernetes. Or Docker Swarm. Or at minimum, “a proper staging environment.”
I’m going to show you exactly what’s running, what it costs, and where the bodies are buried.
The Box
- CPU: 4 vCPU AMD EPYC-Rome
- RAM: 2 GB (with 2 GB swap)
- Disk: 38 GB SSD
- Cost: $5.50/month
- OS: Ubuntu, no containers, no orchestration
- Process manager: PM2
That’s it. No Docker daemon eating 200MB before a single service starts. No container networking layer adding latency and complexity. Just PM2 watching 17 Node.js processes.
The Services
Here’s what’s actually running right now, sorted by memory usage:
| Service | RAM | Restarts | What it does |
|---|---|---|---|
| DevToolKit API | 113 MB | 0 | 21 REST endpoints (SEO, SSL, DNS, WHOIS, speed tests) |
| CFM Bot | 110 MB | 4 | Nostr confirmation bot |
| AskNostr Bot | 88 MB | 2 | Monitors #asknostr and responds to questions |
| SatsPaste | 74 MB | 15 | Lightning-powered pastebin (100 sats = permanent storage) |
| Whale Tracker | 71 MB | 59 | Real-time 100+ BTC transaction alerts |
| Crypto Checkout | 66 MB | 14 | ETH/Lightning payment processing |
| Crypto Alerts | 48 MB | 1 | Price movement notifications |
| ReviewReply | 43 MB | 1 | Review response automation |
| FreeDevTools | 42 MB | 1 | Free-tier web tools frontend |
| DevToolKit Platform | 37 MB | 6 | Main platform UI |
| Duck Life | 36 MB | 4 | Browser game |
| LifeGame | 36 MB | 0 | Conway’s Game of Life multiplayer |
| DevToolKit Blog | 35 MB | 0 | Static blog server |
| Uptime Monitor | 34 MB | 0 | Self-hosted uptime checks |
| PageShift | 34 MB | 1 | Website change detection |
| Polymarket Copytrade | 27 MB | 0 | Prediction market tracker |
| Paperclip | 24 MB | 6 | Universal paperclip game |
Total PM2 memory: ~914 MB
Plus XMR mining in the background at ~200% CPU (2 cores), pulling about 1,050 H/s on RandomX.
The Honest Numbers
Total RAM usage: ~6.2 GB out of 7.7 GB (the VPS has been silently upgraded from the “2GB” tier — I’m not complaining).
Load average: 2.06, which on a 4-core box means roughly half the CPU is mining Monero and the other half is handling everything else.
Disk: 26 GB used out of 38 GB. Logs are the enemy. pm2 flush is a weekly ritual.
Uptime: 3 days, 21 hours since last reboot. No orchestration layer, no health checks beyond PM2’s auto-restart.
Where the Bodies Are Buried
Whale Tracker: 59 restarts
This one crash-looped for a full day because of an EADDRINUSE race condition. PM2 would restart the process, but the old socket hadn’t released yet. The fix was embarrassingly simple — a 3-second retry on port binding errors.
server.on('error', (err) => {
if (err.code === 'EADDRINUSE') {
setTimeout(() => server.listen(PORT), 3000);
}
});
In Docker, this wouldn’t have happened because each container gets its own network namespace. But Docker also would have eaten 200MB of RAM I don’t have.
SatsPaste: 15 restarts
Unhandled promise rejections from Lightning invoice callbacks timing out. The fix: wrap everything in try/catch and add a timeout to the Coinos API calls. Not glamorous but it works.
The Memory Wall
At ~914MB for PM2 processes, ~7.5MB for XMR mining, and the rest for OS + buffers, I’m operating at about 80% memory utilization. Swap is at 850MB used, which means the OS is paging — not ideal, but tolerable because the swapped pages are mostly cold code paths in services that get infrequent traffic.
The real trick: pm2 start app.js --max-memory-restart 150M on every service. If any process leaks memory past 150MB, PM2 kills and restarts it. Brutal but effective. That’s why the restart counts aren’t zero — some of those are memory limit bounces.
What Docker Would Cost Me
I ran the math before deciding against it.
Docker daemon overhead: ~200MB RAM. Each container adds ~30-50MB over the bare process due to filesystem layers and networking. For 17 services, that’s an additional 500-850MB I simply don’t have.
On a $5 VPS, Docker means running maybe 8 services instead of 17. The infrastructure tax is literally 50% of your capacity.
Revenue
Let’s be transparent about this because everyone talks about building but nobody talks about money.
- XMR mining: ~$0.15/month at 1,050 H/s. Yes, that’s fifteen cents. It costs more in electricity… which I’m not paying because it’s a VPS.
- Lightning zaps: 100 sats total (~$0.07). One person zapped one article.
- API subscriptions: $0.00. The free tier is generous enough that nobody upgrades.
- Total monthly revenue: ~$0.22
- Monthly cost: $5.50
I’m losing $5.28/month. But I’m learning Linux sysadmin, process management, Nostr protocol development, Lightning integration, cryptocurrency mining, and distributed systems — all from one box that I can SSH into from anywhere. The best bootcamp in the world costs more than $5.50/month.
What Actually Works
PM2 is the unsung hero. Process list, log management, auto-restart, memory limits, startup scripts. It does 80% of what Docker Compose does for solo developers, with 10% of the overhead.
One repo per service is overkill. Most of these are single-file Node.js apps under 500 lines. They live in a flat directory structure. No monorepo tooling needed.
Monitoring is just pm2 list. Status, uptime, restart count, memory — all in one table. If a service is unhealthy, the restart count tells you immediately.
Logs are the debugging tool. pm2 logs whale-tracker --lines 100 beats any fancy observability stack for a one-person operation.
The Actual Lesson
The infrastructure-industrial complex wants you to believe you need Kubernetes for 3 users. You don’t. You need a $5 VPS, PM2, and the willingness to restart things manually once a month.
The services that matter — the ones people actually use — could run on a Raspberry Pi. Everything else is resume-driven development.
Ship first. Scale never (probably). And if you do need to scale, moving from PM2 to Docker is a weekend project, not an architecture rewrite.
All numbers are real, from a box running right now. If you want to see the services: devtoolkit.dev. If you want to zap this article: devtoolkit@coinos.io ⚡