Published minimums describe the smallest configuration in which software starts, not the smallest in which it works, and the gap is usually a factor of two to four. This guide gives measured planning figures for 22 self-hosted applications, the four consumers of a server that sizing usually forgets, the arithmetic for running several applications together, and the commands that tell you whether you got it right.

There is a reason the figures below sit above the ones in project READMEs, and it is not caution. A stated minimum is partly a marketing number: it has to be low enough that nobody is discouraged from trying the software. The number worth planning against is different, and it is the one at which the application still behaves while the database cache is warm, a backup is running, and somebody is actually using it.

MassiveGRID per-resource pricing, so you buy the shape you need rather than a plan tier: $2.87 per CPU core, $0.80 per GB RAM, $0.01 per GB SSD per month in New York, London and Frankfurt. 1 TB of transfer included. Annual billing takes 20% off.

Cloud VPS — from $1.99/mo · Dedicated VPS for guaranteed cores
Fully managed if you would rather not patch it yourself

The Four Things That Consume a Server

Sizing goes wrong when only the application is counted. There are four consumers, and three of them are easy to forget.

The application runtime. A Go binary uses tens of megabytes. A Rails or Python application forks workers, each holding a full interpreter, so memory scales with concurrency rather than with users.

The database. PostgreSQL wants roughly a quarter of system memory for its cache to perform well. On a 4 GB server that is a gigabyte you cannot give the application.

Peak operations. Asset compilation, container rebuilds, database migrations and backup compression are all transient and all larger than steady state. Servers fail during these, not during normal use.

The operating system. Roughly 300 to 500 MB for Ubuntu with a few services, before anything you installed.

What Each Application Actually Needs

Planning figures for a small production deployment, meaning a handful to a few dozen users, with the database and the application on one server. Prices are the MassiveGRID monthly rate for that configuration.

ApplicationConfigurationMonthlyWhat drives it
ntfy1 vCPU / 1 GB / 16 GB$3.83Almost nothing. A Go binary
Uptime Kuma1 vCPU / 2 GB / 16 GB$4.63Number of monitors and check frequency
Vaultwarden1 vCPU / 2 GB / 32 GB$4.79Rust, very light. Attachments only
Headscale1 vCPU / 2 GB / 32 GB$4.79Coordination only, not traffic
Forgejo1 vCPU / 2 GB / 32 GB$4.79Repository size, and CI if colocated
Umami1 vCPU / 2 GB / 32 GB$4.79Event volume in the database
Ghost2 vCPU / 2 GB / 32 GB$7.66Node process plus image storage
Stirling PDF2 vCPU / 4 GB / 32 GB$9.26JVM, and document size when processing
BookStack2 vCPU / 4 GB / 64 GB$9.58PHP plus MySQL. Modest
Outline2 vCPU / 4 GB / 64 GB$9.58Node, Postgres and Redis together
Mattermost2 vCPU / 4 GB / 64 GB$9.58File uploads over time
Home Assistant2 vCPU / 4 GB / 64 GB$9.58Entity count and recorder retention
Discourse2 vCPU / 4 GB / 64 GB$9.58Rebuilds are the memory peak
Paperless-ngx2 vCPU / 4 GB / 128 GB$10.22OCR is CPU-heavy on ingest
Strapi2 vCPU / 4 GB / 64 GB$9.58Build step needs more than runtime
Authentik2 vCPU / 4 GB / 64 GB$9.58Server plus worker plus Postgres and Redis
MinIO2 vCPU / 4 GB / 64 GB+from $9.58Storage, entirely. Compute is minimal
Jellyfin4 vCPU / 8 GB / 128 GB+from $19.16Transcoding. Direct play needs almost nothing
Immich4 vCPU / 8 GB / 128 GB+from $19.16Machine learning on import, then storage
Matrix Synapse4 vCPU / 8 GB / 128 GB$19.16Federation. Large rooms are expensive
Supabase4 vCPU / 8 GB / 128 GB$19.16Ten containers. The heaviest of the small stack
Odoo4 vCPU / 8 GB / 128 GB$19.16One worker per concurrent request, ~1 GB each

Rows marked with a plus are storage-led: the price is the starting configuration and the disk is the line you will grow. Treat all of these as starting points to measure from, not as specifications. Two deployments of the same application with different usage patterns diverge quickly, and the only figure that describes your instance is the one you observe on it.

The Patterns Behind the Numbers

Four rules cover most of the table, and knowing them lets you size an application that is not on it.

Language runtime sets the floor. Go and Rust applications sit in tens of megabytes. Node and PHP land in hundreds. Python, Ruby and Java want a gigabyte before doing anything useful, and Java in particular reserves heap on the basis of total system memory unless told otherwise.

Container count multiplies. An application distributed as eight containers pays the runtime cost eight times. Supabase and Authentik are heavier than their function suggests for precisely this reason.

The peak is not the average. Discourse rebuilds, Strapi builds and Paperless OCR runs are several times steady-state consumption. Size for the peak or add swap, which turns a crash into a slow minute.

Storage grows on a different curve from compute. Photos, media, documents and file uploads accumulate indefinitely while CPU need stays flat. This is the argument for buying resources separately rather than in plan tiers, because a plan sized for the disk you will need in two years means paying for cores you never use.

Running Several Apps on One Server

You cannot add the rows. Three applications each wanting 4 GB do not need 12 GB, because the operating system is shared and idle applications are mostly resident rather than active. But you also cannot pretend the cost is nothing.

A workable approach: take the largest single requirement, add roughly 60 percent of each additional application's figure, then add a gigabyte for the operating system and headroom. Uptime Kuma, ntfy, Vaultwarden and Forgejo together fit comfortably in 4 GB. Add Immich to that set and you need 8.

The one thing not to share is a peak. Two applications that both rebuild or reindex on a schedule should not do it at the same hour, and that is a cron decision rather than a hardware one.

Where several applications genuinely share a box, a platform layer is worth the overhead. Coolify and Dokploy both handle reverse proxying, certificates and deployment for a set of applications, at a cost of roughly 1 GB for the platform itself.

Measuring Instead of Guessing

After a week of real use, look at what the server is actually doing:

# memory, and how much is cache rather than in use
free -h

# per-container consumption
docker stats --no-stream

# whether the CPU is waiting on disk
vmstat 1 5

# has anything been killed for memory?
journalctl -k | grep -i 'killed process'

Read those numbers correctly, because two are commonly misread. High memory use with most of it in buff/cache is healthy: Linux uses free memory as page cache and releases it under pressure. And the number that means you are short of memory is not usage, it is swap activity, the si and so columns in vmstat. Sustained non-zero values there are the signal to add RAM.

For CPU, the column to watch is wa, iowait. A high figure means the processor is idle waiting on storage, and adding cores will do nothing. That is a storage problem, and it is why NVMe rather than SATA matters more than core count for database-backed applications.

When Shared Cores Stop Being Enough

Most of the applications above run happily on shared vCPU, because they are idle most of the time and burst briefly. Three cases justify guaranteed cores on a Dedicated VPS.

Sustained CPU work: transcoding in Jellyfin, OCR in Paperless, machine learning on import in Immich. Latency-sensitive work, where a variable response time is itself the problem. And operations that must complete predictably, notably Discourse rebuilds and Odoo month-end reporting, where contention turns a five-minute job into an unpredictable one.

Buying the Shape Rather Than the Tier

The table above prices each configuration exactly, which is possible because MassiveGRID charges per resource: $2.87 per core, $0.80 per GB of RAM and $0.01 per GB of SSD per month. A memory-heavy application does not force you into a plan with cores attached, and a storage-heavy one does not force you to buy either.

That matters most for the growth curve. Immich or MinIO need storage added repeatedly and compute almost never, and independent scaling means each of those adjustments costs only what it is. Annual billing removes a further 20 percent, and longer terms more.

Underneath, every instance sits on a Proxmox high-availability cluster with automatic failover and Ceph storage that replicates every block three times across independent NVMe drives, in any of the 85+ metros we deploy into. For an application holding photos, documents or a message archive, that replication is the part that matters most and it is included rather than an upgrade.

Configure a Cloud VPS from $1.99/mo, or read the true cost of self-hosting for the operational side of the same arithmetic.

Further Reading