Server administrationWritten by GLWS11 min readUbuntu 24.04 LTS / AlmaLinux 9
Commands run on your server unless a section says otherwise. Replace example usernames, addresses and paths with your own values. Keep a working session open when changing remote access.

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.

Both systems: measure what the base system uses
free -m
ps -eo pid,rss,comm --sort=-rss | head -n 10
Measure a slow VPS before making changes: CPU and steal time with top or vmstat, available memory and swap with free, disk latency with iostat, and network reachability with ping or mtr.
Measure a slow VPS before making changes: CPU and steal time with top or vmstat, available memory and swap with free, disk latency with iostat, and network reachability with ping or mtr.

Workloads 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.

Both systems: see each service's memory use
systemctl status nginx mariadb php8.3-fpm 2>/dev/null | grep -E "Memory|Active:"
ps -eo pid,rss,comm --sort=-rss | head -n 10

Workloads 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.

Both systems: check the current state
free -h
swapon --show
cat /proc/sys/vm/swappiness

Trim 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.

Both systems
systemctl list-unit-files --state=enabled --type=service | head -n 40
systemctl list-units --type=service --state=running
MariaDB: example limit (add to a file in the config directory, then restart)
[mysqld]
innodb_buffer_pool_size=128M
max_connections=40
RECORDED LAB OUTPUT · Ubuntu 24.04 LTS · 1 GB VM
               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	40
Recorded idle lab footprint on a nominal 1 GB VM with bounded MariaDB, Nginx and PHP-FPM. Real workloads need measurement under load; vendor-provided swap is shown.

Watch 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.

Both systems
free -m
sudo journalctl -k --since "7 days ago" | grep -i -E "out of memory|oom"
vmstat 5 5

Know 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.