Docker is the most common reason a cheap VPS starts swapping. Containers themselves are lightweight — the overhead is a few hundred megabytes, not gigabytes — but people routinely size them like virtual machines and then wonder why a 1 GB plan dies under three containers. The reality is friendlier: a well-sized Docker stack fits comfortably on plans most budget buyers already own, if you understand what each piece actually consumes.
The fixed costs are small and predictable: a minimal Linux install plus the Docker engine idles around 300–500 MB of RAM before you run anything. Everything after that is a function of your images and workloads. Before you upgrade to a bigger plan, measure what you have — the plans in our comparison table show how little you need to pay for a usable Docker host.
Realistic footprints for common containers
These are idle-to-light-load numbers from real deployments on 2 vCPU budget VPSes. Peak usage during traffic spikes runs higher, but steady-state is what determines whether you fit:
| Container | Steady RAM | Disk (image + data) | Notes |
|---|---|---|---|
| Nginx reverse proxy | 15–30 MB | 150–200 MB | Negligible; runs everywhere |
| Node.js app (Express) | 80–150 MB | 350–500 MB | Grows with traffic and leaks |
| Python (FastAPI/Django) | 120–250 MB | 500–800 MB | Gunicorn workers multiply this |
| WordPress + PHP-FPM | 250–450 MB | 1–2 GB | PHP workers are the RAM hog |
| MySQL / MariaDB | 300–500 MB | 2–5 GB | Buffer pool is configurable |
| Redis | 50–200 MB | small | Set maxmemory, always |
What fits on each plan size
- 1 GB RAM — reverse proxy + one app container + SQLite or a tiny Redis. Fine for a side project, staging, or a single low-traffic site.
- 2 GB RAM — the sweet spot: web server + app + MariaDB + Redis for one or two production apps, with swap as a safety net.
- 4 GB RAM — three to five services comfortably: multiple apps, a real database, background workers, plus headroom for build steps.
The single biggest mistake on small plans is running a database container without capping its memory. MySQL’s default buffer pool can claim half your RAM before you write any application code. Set limits explicitly in the compose file:
services:
db:
image: mysql:8
mem_limit: 512m
command: --innodb_buffer_pool_size=256M
app:
image: myapp:latest
mem_limit: 384m
restart: unless-stopped
Disk: where Docker surprises people
Images are layered, so every apt install in a Dockerfile multiplies across versions. A few stale images and dangling layers can eat 10+ GB on a 40 GB plan. Check before you panic-buy storage:
docker system df
docker image prune -a # remove unused images
docker system prune -f # reclaim dangling layers
Logs are the other silent consumer — a chatty app writing to stdout can grow gigabytes of JSON logs per week. Set log rotation in the daemon config or compose, and add logrotate for bind-mounted logs. Combined with volume data (databases, uploads), a realistic Docker stack on a 40–80 GB plan has room to breathe.
Measure before you size
Guessing your container footprint is how people end up on 8 GB plans running a single blog. Two commands give you ground truth in under a minute:
docker stats --no-stream # live RAM per container
docker ps -s # per-container disk usage
Let the stack run under real traffic for a few days and record the peaks — docker stats shows average and peak-ish readings per container, and your provider’s dashboard shows the host-level memory graph. Size the plan to the peak, plus 20–30% headroom for deploys and spikes. If peak usage sits under 70% of a 2 GB plan for two weeks straight, you don’t need a bigger VPS — you need better limits, not more RAM.
Also check swap pressure before blaming the plan. If the host’s free -h shows swap in active use during normal operation, containers are exceeding their limits and a 1 GB upgrade will only postpone the problem. Fix the limits first; upgrade second.
Swap and OOM: making 2 GB feel like 3
Budget plans rarely include much swap by default. Adding a 1–2 GB swapfile costs nothing and absorbs transient spikes — builds, cache warmups, backup runs — that would otherwise trigger the OOM killer mid-request. It won’t save you from sustained overload, but it converts most “random crash” reports into “slow for a minute.” Pair it with mem_limit on every container and your Docker host stays predictable.
Docker on a budget VPS is a solved problem: measure first, cap your containers, and prune your images, and a 2 GB plan runs a serious stack. If you want maximum hardware per dollar for container workloads, Contabo’s plans are known for aggressive RAM-to-price ratios that leave Docker stacks plenty of headroom: see Contabo’s current VPS pricing. And before you commit to any host, compare plans side by side so your container budget buys actual RAM, not marketing.



