VPS Memory Management: Tuning Swap, OOM Killer, and Kernel Parameters for Better Performance

Memory is the most constrained resource on a budget VPS. While you can often add more CPU or disk space by scaling up, RAM is expensive and limited — especially on plans with 1 GB or 2 GB of memory. Understanding how to actively tune Linux memory management is essential for squeezing the best performance out of your hardware. This guide walks through practical tuning of swap, the Out-of-Memory (OOM) Killer, and key kernel parameters. When choosing a VPS, compare VPS plans with different RAM configurations to find the right balance for your workload.

How Linux Uses RAM: Reading the Numbers Correctly

Before tuning anything, you need to interpret free -h output correctly:

               total        used        free      shared  buff/cache   available
Mem:           1.9Gi       1.1Gi       145Mi       123Mi       695Mi       612Mi

The available column is what matters — memory that can be reclaimed by the kernel when applications need it. A low “free” value is normal and desirable on Linux because unused RAM is better used for disk caching. The buff/cache value is not wasted memory; it accelerates file I/O. A well-tuned server will show “available” as the only real indicator of spare capacity.

Tuning Swap Configuration for Low-Memory VPS

Swap is disk space used as overflow memory when RAM fills up. It is roughly 1000x slower than RAM, but it prevents the system from crashing under load. The key is configuring swap so it acts as a safety net without causing performance degradation.

Swap Size Recommendations

For VPS instances, follow these guidelines:

  • 1 GB RAM or less: Swap equal to 2x RAM (e.g., 2 GB swap for 1 GB RAM).
  • 2–4 GB RAM: Swap equal to RAM size.
  • 4 GB+ RAM: 2 GB swap is usually sufficient.

On VPS plans with NVMe or SSD storage, swap performance is acceptable for occasional use. On spinning disks, heavy swap usage will cripple I/O. Configure swap with fallocate:

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# Make permanent:
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Tuning vm.swappiness: When Does the Kernel Swap?

The vm.swappiness parameter (0–100) controls how aggressively the kernel swaps memory pages out of RAM. The default value on most distributions is 60, which is too aggressive for a VPS with limited RAM — the kernel starts swapping when memory usage hits just 40%.

For a 1–2 GB VPS, lower swappiness keeps critical processes in RAM longer:

# Check current value
cat /proc/sys/vm/swappiness

# Set to 10 (swap only under real memory pressure)
sudo sysctl vm.swappiness=10

# Make permanent
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf

A swappiness of 10 means the kernel starts swapping only when approaching 90% memory pressure. Your applications run in RAM as long as possible. For database servers (MySQL, PostgreSQL), consider setting swappiness as low as 1 to prevent the kernel from swapping out database buffer pages.

Protecting Critical Services from the OOM Killer

The OOM Killer is the kernel’s last resort when memory is completely exhausted. It selects a process to kill based on an oom_score that factors in memory usage, runtime, CPU time, and process hierarchy. You can influence which processes get killed by adjusting oom_score_adj:

# Protect MySQL from OOM Killer (lower score = less likely to be killed)
sudo sh -c 'echo -500 > /proc/$(pgrep mysqld)/oom_score_adj'

# Make a non-essential background task more likely to be killed
sudo sh -c 'echo 500 > /proc/$(pgrep some-background-job)/oom_score_adj'

# Disable OOM killing for a critical process (use cautiously!)
sudo sh -c 'echo -1000 > /proc/$(pgrep sshd)/oom_score_adj'

Values range from -1000 (OOM killer disabled for this process) to 1000 (always killed first). Use -1000 sparingly — if you protect too many processes, the system may hang instead of recovering. A practical approach: protect your database and SSH daemon, and let the OOM Killer handle web server workers — they are easy to restart.

Tuning vm.vfs_cache_pressure for Filesystem Metadata

The vm.vfs_cache_pressure parameter (0–200) controls how aggressively the kernel reclaims memory used for inode and dentry caches (filesystem metadata). For a memory-constrained web server, increasing this value frees RAM for applications:

# Reclaim filesystem metadata cache more aggressively
sudo sysctl vm.vfs_cache_pressure=150

# Make permanent
echo "vm.vfs_cache_pressure=150" | sudo tee -a /etc/sysctl.conf

The trade-off: slightly slower file operations (directory listings, stat calls) in exchange for more RAM available to your web applications and database. On a VPS running a database server, this is almost always a net positive.

Dirty Page Tuning: Preventing I/O Stalls

The kernel buffers writes in memory (dirty pages) before flushing them to disk. Two parameters control this behavior:

  • vm.dirty_background_ratio (default 10): % of memory that can be dirty before background flushing starts.
  • vm.dirty_ratio (default 20): % of memory that can be dirty before processes block waiting for writes to complete.

On a low-memory VPS, lower values prevent large dirty page buildups that cause sudden I/O spikes:

# Flush dirty pages sooner
sudo sysctl vm.dirty_background_ratio=5
sudo sysctl vm.dirty_ratio=10

Complete Memory Tuning Configuration for 1-2 GB VPS

Create /etc/sysctl.d/99-memory-tuning.conf with these consolidated settings:

# Swap behavior
vm.swappiness=10

# Reclaim filesystem metadata cache
vm.vfs_cache_pressure=150

# Reserve minimum free memory for kernel allocations
vm.min_free_kbytes=65536

# Flush dirty pages sooner
vm.dirty_background_ratio=5
vm.dirty_ratio=10

# Reduce memory overcommit
vm.overcommit_memory=2
vm.overcommit_ratio=50

Apply with sudo sysctl -p /etc/sysctl.d/99-memory-tuning.conf and verify with sysctl vm.swappiness vm.vfs_cache_pressure vm.min_free_kbytes.

Monitoring Your Tuning Results

After applying changes, monitor the system for a few days:

# Real-time memory usage
watch -n 2 free -h

# Top memory consumers
ps aux --sort=-%mem | head -10

# Check for OOM events
sudo journalctl -k | grep -i "oom\|out of memory"

# Monitor swap activity
vmstat 2 10

If you see persistent swap usage even with swappiness=10, your VPS simply needs more RAM. Tuning optimizes how efficiently you use available memory, but it cannot create memory out of thin air. Compare VPS plans to find a provider offering the RAM your workload needs.

Conclusion

Linux memory management does not have to be a black box. By tuning swap size, vm.swappiness, OOM Killer protections, vfs_cache_pressure, and dirty page ratios, you can significantly improve how your VPS handles memory pressure. Start with the consolidated configuration above, monitor for a few days, and adjust based on your specific workload. When your application consistently needs more RAM than tuning can provide, it is time to upgrade to a VPS with more memory.

Leave a Reply