VPS Memory Optimization: Reduce RAM Usage, Configure Swap, and Fix OOM Kills

VPS Memory Optimization: Reduce RAM Usage, Configure Swap, and Fix OOM Kills

The Linux OOM (Out of Memory) killer is one of the most disruptive VPS events — when RAM is exhausted, the kernel kills processes to free memory, often taking down your web server, database, or application without warning. Memory pressure builds gradually: small leaks accumulate, traffic spikes fill RAM, or a new service is added without adjusting existing process limits. This guide diagnoses memory usage, configures swap as a safety valve, and tunes service configurations to reduce the memory footprint.

Step 1: Diagnose Current Memory Usage

# Overview: how much RAM is used, free, and available
free -h

# Sample output showing a problem — no swap!
#               total        used        free      shared  buff/cache   available
# Mem:           1.9G        1.7G         82M         45M        180M        185M
# Swap:            0B          0B          0B   <-- No swap! Dangerous.

# Top 15 processes by memory consumption
ps aux --sort=-%mem | head -16

# Memory usage per process (RSS = actual RAM used)
ps -eo pid,comm,rss --sort=-rss | awk 'NR<=15 {printf "%6d MB  %s\n", $3/1024, $2}'

# Check if OOM killer has fired recently
sudo dmesg | grep -i "oom\|killed process" | tail -20
sudo journalctl -k | grep -i "oom\|out of memory" | tail -20

Step 2: Add Swap Space (Critical for Small VPS)

Swap gives the kernel a safety valve — instead of OOM-killing processes, it moves inactive memory pages to disk. On NVMe SSDs, swap performs at 500–1000 MB/s — fast enough to prevent crashes for short bursts without noticeably impacting performance.

# Create a 2 GB swap file (recommended: 2× RAM for VPS with ≤2 GB)
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# Verify swap is active
free -h   # Swap row should now show 2.0G

# Make permanent across reboots
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Step 3: Tune vm.swappiness

vm.swappiness controls how aggressively the kernel moves pages to swap. Default is 60 (quite aggressive). For a VPS where you want to use RAM fully but avoid OOM kills:

# View current value
cat /proc/sys/vm/swappiness   # Usually 60

# Set to 10: prefer RAM but swap when genuinely tight
sudo sysctl vm.swappiness=10

# Make permanent
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
  • vm.swappiness=10: Use RAM first, swap only when tight — good for web servers
  • vm.swappiness=1: Swap only as absolute last resort — good for database servers
  • vm.swappiness=60: Default — too aggressive for most VPS workloads

Step 4: Reduce PHP-FPM Memory Usage

PHP-FPM’s process pool is the most common RAM overconsumption source. Each PHP-FPM worker uses 30–80 MB depending on WordPress plugins loaded.

sudo nano /etc/php/8.2/fpm/pool.d/www.conf
# For a 1 GB VPS:
pm = dynamic
pm.max_children = 5        # Total PHP processes maximum
pm.start_servers = 2        # Processes at startup
pm.min_spare_servers = 1    # Minimum idle processes
pm.max_spare_servers = 3    # Maximum idle processes
pm.max_requests = 500       # Restart each worker after 500 requests (clears memory leaks)

# For a 2 GB VPS:
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5

# For a 4 GB VPS:
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 8
sudo systemctl restart php8.2-fpm

# Monitor PHP-FPM memory usage
watch -n5 'ps aux --sort=-%mem | grep php-fpm | head -10'

Step 5: Right-Size MariaDB/MySQL Buffer Pool

MariaDB’s innodb_buffer_pool_size often defaults to or gets misconfigured at 1 GB+ — too large for small VPS instances.

sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
# For 1 GB VPS:
innodb_buffer_pool_size = 64M

# For 2 GB VPS:
innodb_buffer_pool_size = 128M

# For 4 GB VPS:
innodb_buffer_pool_size = 512M

# General memory savings
query_cache_type = 0         # Disable query cache (causes contention, wastes RAM)
tmp_table_size = 32M
max_heap_table_size = 32M
max_connections = 50         # Reduce from default 151
sudo systemctl restart mariadb

Step 6: Reduce Nginx Worker Memory

sudo nano /etc/nginx/nginx.conf
worker_processes auto;           # Match CPU count (auto is correct)
events {
    worker_connections 512;      # Reduce from 1024 for low-RAM VPS
}

http {
    keepalive_timeout 30;        # Reduce from 65 — frees connections faster
    keepalive_requests 100;      # Limit persistent connection reuse
}

Step 7: Protect Critical Processes from OOM Killer

The kernel assigns OOM scores (higher = more likely to be killed). Protect critical services:

# Add to systemd service files to protect SSH from OOM kills:
sudo nano /etc/systemd/system/ssh.service.d/oom.conf
[Service]
OOMScoreAdjust=-1000   # -1000 = never kill this process
# Also protect Nginx:
sudo mkdir -p /etc/systemd/system/nginx.service.d/
sudo nano /etc/systemd/system/nginx.service.d/oom.conf
[Service]
OOMScoreAdjust=-500
sudo systemctl daemon-reload

Memory Usage Targets by VPS Size

Total RAM Swap Size Stack Recommendation
1 GB 2 GB Nginx + PHP-FPM (3 workers) + MariaDB (64 MB) + Redis (32 MB)
2 GB 2 GB Nginx + PHP-FPM (8 workers) + MariaDB (128 MB) + Redis (64 MB)
4 GB 2 GB Nginx + PHP-FPM (15 workers) + MariaDB (512 MB) + Redis (128 MB) + Docker
8 GB 4 GB Full stack: monitoring, multiple apps, databases, Docker containers

Getting Started

Memory optimization is most critical on smaller Ubuntu VPS plans. The swap configuration and PHP-FPM tuning here keep a 1–2 GB VPS stable under normal traffic. When memory optimization is exhausted and the VPS still runs hot, upgrading to the next RAM tier is the right solution — VPS.DO allows plan upgrades without migrating to a new server.

Conclusion

VPS memory management follows a clear priority: add swap as a safety valve (prevents OOM kills during temporary spikes), reduce PHP-FPM process counts to match available RAM, right-size the MariaDB buffer pool, and protect critical services from OOM score. A 1 GB VPS can reliably run WordPress with proper PHP-FPM tuning and 2 GB swap. The OOM killer is the symptom — the configurations above address the root causes.

Fast • Reliable • Affordable VPS - DO It Now!

Get top VPS hosting with VPS.DO’s fast, low-cost plans. Try risk-free with our 7-day no-questions-asked refund and start today!