The OOM Killer (Out-Of-Memory Killer) is a Linux kernel component that, when available RAM is completely exhausted, selects and terminates processes to free memory and prevent the system from locking up entirely. If you find lines like Killed process 1234 (php-fpm) in your logs, the OOM Killer was responsible.
This guide explains how to detect OOM Killer activity, why it happens more often on VPS servers (where RAM is limited and fixed), and what concrete steps prevent it from killing your critical processes.
How the OOM Killer works
Linux uses an optimistic memory allocation strategy: it lets processes reserve more RAM than physically exists, assuming they will never all demand it at once. This is called overcommit. When that assumption fails — multiple processes claim their memory simultaneously — the kernel enters an OOM crisis.
At that point the kernel calculates an oom_score for every process based on how much memory it is using, how long it has been running, and whether it is marked as "expendable." The process with the highest score dies first.
The typical result on an undersized or misconfigured VPS:
- MySQL or MariaDB dies in the middle of the night and the website goes down.
- PHP-FPM is killed and every page returns a 502 error.
- A backup job consumes extra RAM and takes down the main application.
How to detect OOM Killer activity
The kernel logs every OOM Killer intervention in the system log. Search for it like this:
# Modern method (systemd)
sudo journalctl -k | grep -i "oom\|killed process"
# Classic method
sudo dmesg | grep -i "oom\|killed process"
# On distros with /var/log/kern.log
sudo grep -i "oom\|killed" /var/log/kern.log | tail -50
A typical log event looks like this:
kernel: Out of memory: Kill process 8423 (mysql) score 247 or sacrifice child
kernel: Killed process 8423 (mysql) total-vm:512MB, anon-rss:320MB
You will see the killed process, its PID, the OOM score, and how much memory it was using. Save that information — it will tell you exactly which process was the trigger.
Common causes on a VPS
VPS servers have fixed RAM and — unlike dedicated servers — many providers do not configure swap by default. The most common causes of memory exhaustion are:
| Cause | Practical example |
|---|---|
| Undersized VPS | 2 GB RAM for MySQL + PHP-FPM + Redis + cron jobs |
| Misconfigured MySQL/MariaDB | innodb_buffer_pool_size at 70-80% of total RAM |
| Too many PHP-FPM workers | pm.max_children = 50 on a 1 GB VPS |
| No swap file | When RAM fills up there is no emergency buffer |
| Memory leaks | WordPress plugin or script that accumulates RAM without releasing it |
| Traffic spike | Viral post or DDoS attack multiplies concurrent requests |
How to prevent the OOM Killer from acting
1. Add swap as an emergency buffer
Swap is slower than RAM (disk vs. memory), but it is a lifesaver when physical memory is momentarily exhausted. On an SSD/NVMe VPS the performance penalty is tolerable for short spikes.
# Create a 2 GB swap file
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# Make it permanent in /etc/fstab
echo "/swapfile swap swap defaults 0 0" | sudo tee -a /etc/fstab
Also tune the kernel's tendency to use swap (swappiness). A low value is better for servers:
# Temporary (lost on reboot)
sudo sysctl vm.swappiness=10
# Permanent
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
2. Tune per-service memory limits
Configure each service to use only what it can afford. For MySQL/MariaDB on a 2 GB VPS:
# /etc/mysql/mariadb.conf.d/99-tuning.cnf
[mysqld]
innodb_buffer_pool_size = 512M # no more than 25-30% of total RAM
key_buffer_size = 32M
max_connections = 50
For PHP-FPM, calculate how many workers fit. If each PHP worker uses ~30 MB and you have 1 GB available for PHP:
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
3. Protect critical processes with oom_score_adj
You can lower the probability of the OOM Killer choosing a specific process by adjusting its score. The range is -1000 (completely immune) to +1000 (first to die).
# Protect MySQL: find the PID first
pid=$(pgrep -x mysqld)
echo -500 | sudo tee /proc/$pid/oom_score_adj
To make this permanent with systemd, add to the service unit:
# /etc/systemd/system/mariadb.service.d/oom.conf
[Service]
OOMScoreAdjust=-500
sudo systemctl daemon-reload
sudo systemctl restart mariadb
A value of -500 means the kernel needs the process to be consuming significantly more memory than others before considering it a candidate. Do not use -1000 unless you are certain: if the process has a memory leak, the entire system will freeze.
4. Monitor RAM usage in real time
Prevention starts with knowing consumption before it explodes:
# Quick summary
free -h
# By process, sorted by memory
ps aux --sort=-%mem | head -20
# Continuous monitor
vmstat 2 10 # every 2 seconds, 10 samples
Tools like Netdata or Prometheus + Node Exporter send alerts when RAM exceeds a threshold — before the OOM Killer intervenes. That is the difference between reacting and preventing.
For more server optimization strategies, check the VPS maintenance resource library on our blog.
5. Consider upgrading RAM or changing plans
If the OOM Killer acts frequently even after proper tuning, the signal is clear: the VPS is undersized for the workload. Scaling to a plan with more RAM is usually cheaper than accumulated support hours and service downtime.
Many providers let you scale RAM without changing your IP or reinstalling. At elenlace.com we help you choose the right plan from the start, saving you these reactive firefighting sessions down the road.
Key takeaways
- The OOM Killer kills processes to save the system when RAM runs out — it is not a bug, it is a kernel emergency mechanism.
- Kernel logs (
journalctl -kordmesg) reveal exactly which process was killed and how much memory it was using. - Adding swap (even 1-2 GB) provides a buffer that prevents OOM kills during short spikes.
- Tuning
innodb_buffer_pool_size, PHP-FPM worker counts, and other per-service limits has the biggest practical impact. oom_score_adjlets you protect critical processes from being the first candidate for termination.- If the problem persists after all tuning, the VPS needs more RAM or an architectural redesign.
Is your VPS still crashing due to memory exhaustion? Contact us: at elenlace.com we analyze your configuration and propose a concrete action plan.
FAQ
Can the OOM Killer damage my data?
It can. If the killed process was a database mid-write, tables may end up in an inconsistent state. MySQL/MariaDB includes automatic recovery on restart (InnoDB crash recovery), but it is not an absolute guarantee. Regular backups remain essential regardless.
How much swap should I add to my VPS?
The classic "double the RAM" rule is overkill for modern servers. For a VPS with 1-4 GB of RAM, 1-2 GB of swap is enough as a buffer. More swap does not fix the root problem — it just postpones it and degrades performance if the system uses swap constantly.
Is it safe to set OOMScoreAdjust=-1000 for MySQL?
Not recommended. With -1000 the process is completely immune to the OOM Killer. If MySQL has a memory leak and consumes all available RAM, the kernel cannot do anything and the entire system will lock up completely. A value of -500 provides strong protection without that extreme risk.
How do I check if the OOM Killer acted if the server rebooted?
If the server rebooted abruptly, check the previous boot's logs: sudo journalctl -k -b -1 | grep -i oom. The -b -1 flag refers to the second-to-last boot. If rotated logs were cleared, tools like last or your provider's panel logs can confirm the outage.
Prefer it done for you? El Enlace handles hosting and professional web development.
Further reading
Other providers and guides worth comparing: