Start with a memory budget
A 1 GB server has about 1,000 MB, and the operating system, SSH and system services take a share before you run anything. A minimal Linux install typically uses somewhere between 100 and 250 MB, depending on the distribution and what is enabled. That leaves roughly 700 to 850 MB for your own software, and you need a margin so that a busy period does not push the server into swap or trigger the out-of-memory killer.
The figures in this guide are rough, because memory use depends on version, settings and traffic. Measure your own server rather than trusting estimates.
free -m
ps -eo pid,rss,comm --sort=-rss | head -n 10Workloads that fit comfortably
These usually run well on 1 GB: a static website or several behind Nginx or Caddy, a small Node.js, Python or Go application, a WireGuard VPN, a personal DNS resolver, a small PostgreSQL or MariaDB database for light use, SQLite-based applications, a Git server such as Gitea or Forgejo for a few users, and simple scheduled scripts.
Go and Rust programs and static files are the lightest. Interpreted applications use more, and each additional worker process multiplies the footprint.
Workloads that are tight
These can work with care and with swap enabled: WordPress with a small plugin set and a tuned PHP-FPM pool, a single Docker container or two, Uptime Kuma, a small Matrix or chat server, or a lightweight monitoring agent. Expect to tune: lower the number of PHP-FPM or application worker processes, shrink database buffers, and avoid running a database, a cache and the application all at once with default settings.
systemctl status nginx mariadb php8.3-fpm 2>/dev/null | grep -E "Memory|Active:"
ps -eo pid,rss,comm --sort=-rss | head -n 10Workloads that need a larger plan
Plan for 2 GB or more for the Docker engine with several containers, for Nextcloud, for a larger WordPress site or a store, for Java applications, for builds that compile code, for GitLab, Elasticsearch and similar search servers, and for heavy databases. Immich and local language models need considerably more, so read their guides for sizing. If an application's own documentation lists a minimum above 1 GB, believe it.
Add swap as a safety net
Swap gives a short spike somewhere to go instead of triggering the out-of-memory killer. It does not make a workload that needs more memory run well, since heavy swapping is slow. A 1 to 2 GB swap file is a sensible addition on a 1 GB server, as the swap guide explains.
free -h
swapon --show
cat /proc/sys/vm/swappinessTrim what you run
Disable services you do not use, and look at what starts at boot. Reduce worker counts in your web and application servers, and cap database memory. For MariaDB, a small innodb_buffer_pool_size such as 128M is a reasonable starting point on a 1 GB server. For PostgreSQL, keep shared_buffers modest. Compare memory before and after each change.
systemctl list-unit-files --state=enabled --type=service | head -n 40
systemctl list-units --type=service --state=running[mysqld]
innodb_buffer_pool_size=128M
max_connections=40 total used free shared buff/cache available
Mem: 955 421 170 3 519 534
Swap: 2399 0 2399
innodb_buffer_pool_size 134217728
max_connections 40Watch for trouble
Check available memory and the kernel log for out-of-memory kills after changes and at busy times. Frequent kills mean the workload does not fit. Alert on high memory use, as the monitoring guide describes, and decide in advance when you will move to a larger plan.
free -m
sudo journalctl -k --since "7 days ago" | grep -i -E "out of memory|oom"
vmstat 5 5Know when to upgrade
Upgrade when swap is in constant use, when services are being killed, or when you are spending more time tuning than the extra memory would cost. The price difference between a 1 GB plan and a 2 GB plan is often smaller than the value of your time. See the guide on moving to a bigger plan for how to do it safely.
Official documentation
These upstream references provide more detail on the commands and workflows in this guide.