$osscostcalc.comSelf-hosting cost intelligence

Self-Hosting on a $5 Droplet: What Actually Fits in 1 GB RAM

9 min read·1,720 words·Architecture

TL;DR

A 1 GB VM is enough for surprisingly serious self-hosting in 2026 — Caddy + SQLite + a Go or PHP-FPM app will happily run Miniflux, Gitea, Vaultwarden, or a small Ghost blog with room to spare. Java, Elasticsearch, GitLab, and anything bundling Chromium will not fit, no matter how much swap you add. This guide walks through what actually runs, how to tune swap and OPcache, and where the cliff is.

TL;DR

A 1 GB VM in 2026 is more capable than the internet gives it credit for. With Caddy, SQLite, and a single-binary Go app or PHP-FPM in static mode, you can comfortably run Miniflux, Vaultwarden, Gitea (small), Shaarli, FreshRSS, or a Ghost blog on a $6 DigitalOcean droplet, a €4.50 Hetzner CX22, or a $5 Linode Nanode. The cliff is sharp: anything that ships a JVM, Chromium, Elasticsearch, or a full Rails app will OOM-kill itself before you finish the install wizard.

The 2026 cheap-tier landscape

The "$5 box" is now a slight misnomer. DigitalOcean's entry Basic Droplet is $6/mo (1 vCPU, 1 GB RAM, 25 GB SSD, 1 TB transfer). Linode/Akamai's Nanode 1 GB is still $5/mo (1 vCPU, 1 GB RAM, 25 GB NVMe, 1 TB transfer). Hetzner's CX22 is roughly €4.51/mo in EU regions and about $5.17 in Ashburn/Hillsboro, with 2 vCPU (shared AMD), 4 GB RAM, 40 GB NVMe, and 20 TB transfer.

That last line is not a typo. Hetzner gives you 4x the RAM, 2x the cores, and 20x the egress for roughly the same money. If you are building a price/performance spreadsheet, Hetzner CX22 wins almost every workload below the $20/mo line — which is exactly the kind of comparison the osscostcalc calculator on this site exists to make obvious.

Provider Plan vCPU RAM Disk Egress Price
DigitalOcean Basic 1 1 GB 25 GB SSD 1 TB $6.00
Linode Nanode 1GB 1 1 GB 25 GB NVMe 1 TB $5.00
Hetzner CX22 (EU) 2 4 GB 40 GB NVMe 20 TB ~€4.51
Hetzner CPX11 (US) 2 2 GB 40 GB NVMe 20 TB ~$4.85

For the rest of this guide I'll assume the harder constraint: 1 GB RAM, 1 vCPU, because that's what DigitalOcean and Linode actually give you at the entry tier. If you're on Hetzner, treat everything below as "with comfortable headroom."

What a fresh 1 GB box actually has free

Boot a Debian 12 minimal image. free -m will report somewhere around 880-920 MB available depending on the kernel and cloud-init shrapnel. By the time you've installed ufw, fail2ban, an SSH config, and unattended-upgrades, you're at roughly 820 MB free. That is your working budget.

Now layer a web stack:

  • Caddy 2.x: 25-40 MB RSS idle, including the autocert manager.
  • PHP 8.3 FPM with 4 workers: ~30 MB shared + ~25 MB per worker = ~130 MB.
  • PostgreSQL 16 default config: 80-120 MB before you tune shared_buffers down.
  • MariaDB 11: 90-150 MB after you strip the performance schema.
  • SQLite: zero. It's a library linked into your app.
  • Redis with default settings: 8-12 MB idle.

The single most consequential decision you make on a 1 GB box is SQLite vs. a real RDBMS. Picking SQLite frees ~100 MB and one persistent process. On a 1 GB host that's not a rounding error — it's the difference between "runs fine" and "swap-thrashing during a backup."

The lightweight stack that just works

My default 1 GB recipe in 2026 is boring and effective:

  1. Caddy as the only public-facing process. Automatic TLS, HTTP/3, reverse proxy, static files. No nginx, no certbot cron job.
  2. SQLite with WAL mode for any app that supports it.
  3. The app as a single binary (Go, Rust) running as a systemd unit, or PHP-FPM in pm = ondemand mode with a low pm.max_children.
  4. No Docker, or Docker only for one container. The daemon alone costs 80-120 MB and the overlay filesystem hides memory pressure from you.
  5. A 2 GB swap file on the same NVMe disk, with vm.swappiness=10.

That stack, on a Hetzner CX22 or a $6 droplet, will host all of the following simultaneously without breathing hard:

  • Miniflux (Go + SQLite or Postgres): ~25 MB RSS.
  • Vaultwarden (Rust + SQLite): ~40 MB RSS.
  • Shaarli (PHP + SQLite-ish flat files): ~5 MB per FPM worker.
  • A static site or two via Caddy file_server.

Total resident usage: under 350 MB, leaving the kernel page cache plenty of room to actually cache your SQLite database in RAM — which is where SQLite's reputation for being "as fast as Redis for reads" comes from.

Tuning PHP-FPM for tiny boxes

The default pm = dynamic config on most distros assumes you have 8 GB and will happily spawn 50 children. On 1 GB this is suicide. Use:

pm = ondemand
pm.max_children = 4
pm.process_idle_timeout = 30s
pm.max_requests = 500

And enable OPcache with realistic settings:

opcache.enable=1
opcache.memory_consumption=64
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.validate_timestamps=1
opcache.revalidate_freq=60

That 64 MB OPcache is shared across all workers, so it's a one-time cost. A WordPress install without OPcache eats ~45 MB per request in compile time alone; with it, you'll see 8-15 MB per worker and 3-4x the throughput on the same CPU.

Swap: friend, not crutch

The Linux mythology that "swap is bad on SSDs" is a holdover from spinning-disk and early-MLC days. On a modern NVMe-backed cloud volume, swap is the difference between a process being OOM-killed at 2 AM and it stuttering for 400 ms while a cold page is faulted back in.

On a 1 GB droplet I always create a 2 GB swap file:

fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
sysctl -w vm.swappiness=10
sysctl -w vm.vfs_cache_pressure=50

Swappiness 10 means the kernel will strongly prefer evicting cached pages over anonymous process memory. That keeps your hot app pages resident and pushes idle daemons (looking at you, snapd, packagekitd, unattended-upgrades) into swap where they belong.

Note that Hetzner's CX line and DO's premium droplets use local NVMe, but DigitalOcean Basic droplets use network-attached SSD. Swap I/O on those is slower and counts toward your shared IOPS budget. Don't lean on swap as a primary workload mechanism there — use it as a safety net, not a tier of memory.

What breaks at 1 GB (the honest list)

These are the apps I have personally watched die or limp on a 1 GB box:

  • GitLab CE / EE. The Omnibus install boots Puma + Sidekiq + Gitaly + Redis + Postgres + Nginx + Prometheus + Workhorse. Documented minimum is 4 GB and they mean it. Use Gitea or Forgejo instead.
  • Elasticsearch / OpenSearch. The JVM default heap is 1 GB. You have 1 GB total. Math is not on your side. Meilisearch (Rust) or Typesense (C++) will do 80% of what you wanted in 80 MB.
  • Mastodon. Ruby + Sidekiq + Streaming (Node) + Postgres + Redis + Elasticsearch (optional). Minimum 2 GB and even that is painful. Use GoToSocial (single Go binary, ~40 MB) for a personal fediverse presence.
  • Nextcloud with previews enabled. Nextcloud itself runs in 1 GB if you're careful, but the preview generator and recognize app will pull in ffmpeg + a TensorFlow model and instantly OOM. Disable them, or run Pico/PicoCMS/Filebrowser instead.
  • Anything with a bundled Chromium. That means Puppeteer, Playwright, headless screenshot services, Sentry's frontend ingest, BrowserBox. Chromium needs ~500 MB just to start.
  • Discourse. 2 GB hard floor, 4 GB realistic. Use Flarum (PHP) if you need a forum.
  • Plausible Analytics self-hosted. Requires ClickHouse, which wants ~1 GB heap on its own. Use Umami (Node + Postgres/MySQL) — it'll fit in 1 GB with Postgres tuned down.

A useful heuristic: if the install instructions tell you to install Docker Compose with more than three services, it won't fit.

Apps I trust on a 1 GB box in production

After running variations of this setup for clients and myself since 2019, here's my actual production list with measured idle RSS:

App Stack Idle RAM Notes
Miniflux Go + SQLite 25 MB RSS reader, rock solid
Vaultwarden Rust + SQLite 40 MB Bitwarden-compatible
Gitea (small) Go + SQLite 80-150 MB Disable actions runner
Forgejo Go + SQLite 90-160 MB Gitea fork, same footprint
FreshRSS PHP-FPM + SQLite 60 MB With OPcache tuned
Shaarli PHP-FPM + flat 40 MB Bookmarking
Ghost (small blog) Node + SQLite 180 MB One of the heavier picks
Umami Node + Postgres 250 MB Analytics, tight fit
Uptime Kuma Node + SQLite 120 MB Disable Chromium checks
Caddy + static site Go 30 MB Honestly use a CDN
WireGuard kernel <5 MB Free VPN headend

You can pick 2-3 of those and run them on the same $6 droplet without issue. On a Hetzner CX22 with 4 GB, you can run almost the entire list at once.

When to step up

The honest tipping points where you should stop fighting and pay for more RAM:

  • You need search beyond LIKE '%foo%'. Step up to 2 GB and run Meilisearch.
  • You need Postgres with more than ~50 MB shared_buffers. Step up.
  • You want any kind of background worker pool (Sidekiq, RQ, Celery with prefork). Step up.
  • You need to run Node and Postgres and Redis and an app server. Step up.

The next tier up — $12/mo at DO, $12 at Linode, ~€7-8 at Hetzner for a CX32 — typically gives you 2x RAM. That single jump unlocks roughly 80% of the "real" self-hosted app catalog (Nextcloud, Mastodon-lite, full Gitea with Actions, Umami at scale).

Decision checklist

Before you click "create droplet," answer these in order:

  1. Does the app have a SQLite mode? If yes, use it. If no, can you tolerate Postgres with shared_buffers=32MB?
  2. Is the runtime Go, Rust, or PHP-FPM? If it's Ruby, Java, or "Docker Compose with 6 services," you are on the wrong tier.
  3. Did you create a 2 GB swap file and set swappiness to 10? If no, do that before installing anything.
  4. Did you enable OPcache (PHP) or the equivalent compile cache for your runtime? Free 2-3x throughput.
  5. Is your egress under 1 TB/mo? If not, you are already on Hetzner whether you knew it or not — DO and Linode bill ~$0.01/GB over.
  6. Did you check the osscostcalc comparison tool for the exact app you want to run? The per-app RAM and egress estimates there will tell you within a minute whether the cheap tier is realistic or wishful thinking.

Run through that list and the $5 droplet stops being a toy. It becomes the most boring, most reliable piece of infrastructure you own.

self-hostingdigitaloceanhetznerlinodesqlitecaddy