What you can realistically self-host on each VPS size
A practical guide to sizing a VPS for self-hosted applications. Shows RAM and disk footprints for common tools, explains memory limits and OOM kills, and identifies which stacks require larger machines.
You size a VPS by the memory and disk your stack will actually use. Tiny VMs handle one light tool. Mid-sized VMs handle a couple of services. Stacks like GitLab or Immich need large VMs. Treat 8 to 16 GB RAM as the realistic range for the heavier end, and budget disk for the application as well as your data.
Before you start
This picks up from a server you can already reach over SSH. The commands below are for AlmaLinux 9 and Ubuntu 24.04.
- Know your base OS footprint. Ubuntu 24.04 Server needs about 1.5 GB RAM to install from ISO or 1 GB for cloud images. AlmaLinux 9 calls for about 1.5 GB RAM to install. That is before you add any apps.
- Plan for swap. Both RHEL/AlmaLinux and Ubuntu document that having swap helps the kernel reclaim memory under pressure. Small VMs without swap run out of memory much sooner.
- Understand what happens when you run out of memory. The kernel’s OOM killer terminates processes. With cgroups v2 the kill can be scoped to a cgroup. Some systems also run systemd-oomd, which can proactively kill units under sustained pressure. In containers the kernel kills the container’s processes and you will see exit code 137 or “OOMKilled”. Expect service restarts and possible database crash recovery.
- Keep SQLite on local disk. Tools like Uptime Kuma store data in SQLite and warn against NFS or SMB shares due to file locking. Use a local disk or block volume and back it up properly.
- Budget disk beyond “user files”. GitLab’s application node wants roughly 40 GB before you store any repositories. Nextcloud and Immich add around 10 to 20 percent storage overhead for thumbnails, versions and transcodes beyond the originals. Under‑sizing the root disk is a common cause of failed upgrades.
- If you are running Nextcloud Talk’s High‑Performance Backend or office suites with Nextcloud, note their extra requirements. Talk HPB calls for about 8 GB RAM. ONLYOFFICE Document Server recommends around 4 GB. Collabora often estimates a baseline around 1 GB plus about 50 MB per active user.
- With Hostworld you manage VPS power controls and rebuilds in Virtualizor from the client area. If you need advice on sizing or a move between plans, please open a support ticket.
Step 1: Check current RAM and swap
This shows how much RAM and swap you have and how much is in use.
Ubuntu 24.04
free -h
swapon --show
uname -a
AlmaLinux 9
free -h
swapon --show
uname -a
Look for a non‑zero “Swap” line. Many Ubuntu cloud images ship without swap. If you have none, add a swap file before you load the machine.
Step 2: Add a swap file if you do not have one
This creates a 1–2 GB swap file, secures it, enables it now, and makes it persistent. A 1 GB VM usually benefits from a 1–2 GB swap file. Swap is not a replacement for RAM, but it reduces abrupt OOM kills.
Ubuntu 24.04
# Create a 2G swapfile (adjust size if needed)
sudo fallocate -l 2G /swapfile || sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
# Secure the file so only root can read/write it
sudo chmod 600 /swapfile
# Format it as swap and enable it immediately
sudo mkswap /swapfile
sudo swapon /swapfile
# Make it persistent across reboots
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# Check the kernel's swappiness (Ubuntu defaults to 60)
cat /proc/sys/vm/swappiness
# Optionally set swappiness persistently (example keeps default 60)
echo 'vm.swappiness=60' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system
# Verify
free -h
swapon --show
AlmaLinux 9
# Create a 2G swapfile (adjust size if needed)
sudo fallocate -l 2G /swapfile || sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
# Secure the file so only root can read/write it
sudo chmod 600 /swapfile
# Format it as swap and enable it immediately
sudo mkswap /swapfile
sudo swapon /swapfile
# Make it persistent across reboots
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# Check the kernel's swappiness
cat /proc/sys/vm/swappiness
# Optionally set swappiness persistently (example sets 60)
echo 'vm.swappiness = 60' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system
# Verify
free -h
swapon --show
Step 3: Check for recent OOM kills
This searches the kernel log for memory‑related kills and shows OOM events from Docker if you use containers.
Ubuntu 24.04
sudo journalctl -k -g OOM --since "24 hours ago" || true
dmesg -T | grep -i -e oom -e "out of memory" || true
docker events --since 1h 2>/dev/null | grep -i OOM || true
docker ps -a --no-trunc --format 'table {{.Names}}\t{{.Status}}' 2>/dev/null | grep -i 137 || true
AlmaLinux 9
sudo journalctl -k -g OOM --since "24 hours ago" || true
dmesg -T | grep -i -e oom -e "out of memory" || true
docker events --since 1h 2>/dev/null | grep -i OOM || true
docker ps -a --no-trunc --format 'table {{.Names}}\t{{.Status}}' 2>/dev/null | grep -i 137 || true
If you see frequent kills, reduce concurrency, add swap, or move to a larger VM.
Step 4: Constrain container memory where appropriate
This runs a container with memory limits so the kernel can contain pressure to that cgroup. In OOM conditions the container will be killed rather than the host’s database. Adjust sizes to your VM.
Ubuntu 24.04
# Example: run Uptime Kuma with memory limits and local disk storage
sudo docker run -d --name uptime-kuma \
-p 3001:3001 \
-v /opt/uptime-kuma:/app/data \
--memory=512m --memory-swap=1g \
louislam/uptime-kuma:1
AlmaLinux 9
# Example: run Uptime Kuma with memory limits and local disk storage
sudo docker run -d --name uptime-kuma \
-p 3001:3001 \
-v /opt/uptime-kuma:/app/data \
--memory=512m --memory-swap=1g \
louislam/uptime-kuma:1
- Keep Uptime Kuma’s data on a local path such as
/opt/uptime-kuma. Do not place the SQLite file on NFS or SMB. - For other containers, apply
--memoryand--memory-swapbased on what the app’s docs state. Immich’s Postgres, for example, should get enough memory and live on local SSD.
Step 5: Set realistic PHP worker limits for WordPress or Nextcloud
This reads your PHP memory limit so you can cap PHP‑FPM workers to what fits in RAM. Each PHP request can use up to the configured limit. WooCommerce advises a 256 MB memory limit for WordPress. Nextcloud recommends 512 MB per PHP process for better headroom.
Ubuntu 24.04
# Check the effective PHP memory_limit seen by CLI
php -i | grep memory_limit
# List top resident memory users
ps -e -o pid,comm,rss --sort=-rss | head
AlmaLinux 9
# Check the effective PHP memory_limit seen by CLI
php -i | grep memory_limit
# List top resident memory users
ps -e -o pid,comm,rss --sort=-rss | head
Work out a safe pm.max_children by budgeting the RAM available to PHP‑FPM divided by the per‑process memory you allow. Leave headroom for the OS, your database and cache. Example: on a 2 GB VM running Nextcloud with memory_limit = 512M, you might permit 2 to 3 PHP workers at most, not the default many‑worker settings. High limits on a small VPS are a frequent cause of OOM.
Step 6: Map applications to realistic VPS sizes
The figures below come from the projects’ own requirements and practical experience where noted. They assume the OS overhead above. Use swap to smooth out bursts, but size RAM to run steadily without constant pressure.
| Application/stack | Realistic RAM | Disk notes | Fits in 1 GB | Fits in 2 GB | Fits in 4 GB | Fits in 8 GB | Fits in 16 GB |
|---|---|---|---|---|---|---|---|
| WordPress core site | 0.5–1 GB with low PHP concurrency | Small. Grows with plugins/uploads | Borderline | Yes | Yes | Yes | Yes |
| WooCommerce shop | 1–2 GB if memory_limit ≥ 256 MB |
Small to medium | No | Maybe, tightly tuned | Yes | Yes | Yes |
| Nextcloud core (no office, no Talk HPB) | ~2 GB with a few PHP workers | User data + ~10% overhead for thumbnails, versions and caches | No | Yes, tuned | Yes, comfortable | Yes | Yes |
| Nextcloud + ONLYOFFICE Document Server | ≥4 GB recommended | As above | No | No | Yes | Yes | Yes |
| Nextcloud + Collabora | ~1 GB baseline + ~50 MB per active editor | As above | No | No | Maybe, light concurrency | Yes | Yes |
| Nextcloud Talk HPB | ~8 GB for HPB component | As above | No | No | No | Yes | Yes |
| Gitea + small database | ~1–2 GB | Repos grow with use | Maybe | Yes | Yes | Yes | Yes |
| GitLab (single node) | 8–16 GB baseline | ~40 GB on app node, plus repos | No | No | No | Maybe, constrained | Yes |
| Uptime Kuma | ≥512 MB floor, 1 GB safer | SQLite on local disk. No NFS/SMB | Yes | Yes | Yes | Yes | Yes |
| Jellyfin or Plex (direct‑play) | ~2 GB is common. CPU/GPU is the limiter | Media storage heavy, but separate | No | Yes | Yes | Yes | Yes |
| Jellyfin or Plex (CPU transcoding) | RAM moderate. CPU becomes the bottleneck | As above | No | Maybe one 720p | Maybe one 1080p | Varies by CPU | Varies by CPU/GPU |
| Immich (photos/videos) | ≥6 GB RAM, 2 vCPU minimum | DB on local SSD. +10–20% for thumbnails/transcodes. DB often 1–3 GB | No | No | Maybe on 6 GB+ | Yes | Yes |
Step 7: Choose safe combinations by VPS size
On 1 GB RAM
- One small WordPress or PHP site with a low PHP‑FPM worker count. Use an external database if you can, or run a very small local MariaDB tuned for low memory. Keep
memory_limitmodest. - A light utility like Uptime Kuma. Keep its data on local disk, not NFS or SMB.
- Do not attempt GitLab, Immich, office suites for Nextcloud, or multimedia transcoding. These do not fit.
On 2 GB RAM
- Nextcloud core with a small MariaDB and Redis if you keep PHP workers low. Budget about 2 GB and monitor.
- Gitea with a small database and a reverse proxy. Room for a light extra like Uptime Kuma.
- Jellyfin or Plex is fine for direct‑play libraries. CPU‑based transcoding still bottlenecks quickly.
- Do not add ONLYOFFICE, Collabora with many concurrent editors, GitLab or Immich.
On 4 GB RAM
- Nextcloud core feels comfortable, including scheduled jobs. Small Collabora use cases may work if concurrency is low.
- Several WordPress sites if you size PHP‑FPM pools per site. Watch MariaDB memory use and PHP
memory_limit. - Jellyfin or Plex with a little more headroom. Still size around CPU limitations for transcoding.
- GitLab remains unsuitable. Immich remains tight below 6 GB.
On 8 GB RAM
- Nextcloud plus an office suite. Keep an eye on memory during peaks.
- Immich meets its stated minimum here if the database is on local SSD and Docker limits are set sanely.
- GitLab can run in a constrained mode but expect trade‑offs. The project’s baseline guidance points you towards larger hardware.
On 16 GB RAM
- GitLab aligns with the current single‑node baseline guidance. Allow extra disk on the application node and separate storage for repositories.
- Immich scales better and has headroom for background jobs. Keep the Postgres database on local SSD.
Step 8: Keep databases within realistic memory
- MariaDB: crashes or OOMs on tiny VMs usually mean buffers are set too high. Use the vendor’s small‑RAM presets and reduce caches for ≤2 GB systems.
- PostgreSQL: as a rule of thumb on a dedicated DB host, start
shared_buffersaround 25 percent of RAM. On a 1 GB VM that suggests about 256 MB, leaving space for connections and the OS page cache.
Measure, then tune in small steps. Restarting a database to test a setting is better than running with constant memory pressure.
What does not fit on a small VPS
- GitLab single‑node. The current guidance is 8 vCPU and 16 GB RAM as a baseline. Memory‑constrained installs exist but are not recommended for production. Treat GitLab as a medium or large VM job, not a tiny VPS job.
- Immich below 6 GB RAM. The quick‑start calls for at least 6 GB and 2 CPU cores. If you set Docker limits, Postgres needs at least 2 GB.
- Nextcloud with office suites on 1–2 GB. ONLYOFFICE or Collabora will exceed headroom fast, then the kernel will kill something. If you need live editing, plan 4–8 GB or more based on concurrency.
- Nextcloud Talk HPB on 1–4 GB. The HPB component calls for about 8 GB.
What happens when RAM runs out
- The kernel’s OOM killer terminates a process based on a badness score. With cgroups v2, kills can be scoped to the offending cgroup instead of taking down an unrelated service.
- On systems with systemd‑oomd, units may be killed proactively when memory pressure is sustained, based on PSI signals.
- In Docker, containers die and report exit code 137.
docker eventsshows “OOMKilled”. - Databases will perform crash recovery at next start. Repeated OOM can corrupt SQLite files. Keep SQLite on local disk and back it up.
What next
If you need more headroom, move to a larger plan in our London or New York locations. See our Linux VPS page.
For planning and hardening once you have provisioned the right size, read more in our VPS guides.
If you want tailored advice for your stack on our platform, please open a support ticket. We will look at your current usage and advise on the next step.
The next step in this playbook is capacity‑aware service configuration, where you set worker counts and database caches to match the RAM you have.
Common questions
Is swap required on a VPS?
It is strongly recommended. Both Ubuntu and RHEL/AlmaLinux document swap as a tool that lets the kernel reclaim memory under pressure. Many Ubuntu cloud images ship without swap. Add a swap file to avoid abrupt OOM kills. Swap is not a substitute for RAM.
Why did my container exit with code 137?
It was killed by the kernel for out‑of‑memory. Check docker events for “OOMKilled” and the kernel log. Set --memory and --memory-swap limits, add swap on the host, and reduce the service’s concurrency.
Can I run GitLab on 4 GB?
No. The current baseline for a single‑node install points to 8 vCPU and 16 GB RAM, with 8 GB as a constrained floor only with trade‑offs. Treat GitLab as a large workload and size disk accordingly.
Is 1 GB enough for Nextcloud?
No for most cases. Nextcloud’s PHP processes alone want 128 MB minimum and 512 MB recommended per worker. A 2 GB VM with carefully sized PHP workers and a small database can run a low‑traffic Nextcloud core. Do not add office suites on 1–2 GB.
Does Jellyfin or Plex need lots of RAM?
Not usually. The limit is CPU or a GPU for hardware acceleration. A 2 GB VM can serve direct‑play libraries. CPU‑based transcoding of multiple 1080p or any 4K streams is unrealistic without more compute.
If you need help deciding the right size on our platform, open a support ticket, or review our Linux VPS options and our VPS guides.