What OOM Killer is and when it triggers
OOM Killer (Out Of Memory Killer) is a Linux kernel mechanism that forcibly terminates processes when RAM and swap run out at the same time. The kernel cannot let the system hang because of a memory shortage, so it picks a "victim" and kills it with SIGKILL. This most often happens on a VDS with 1-2 GB of RAM without configured swap, when MySQL, PHP-FPM, or a Java application suddenly spike their memory usage.
It is important to understand: OOM Killer is a protective mechanism, not a bug. If it triggered, the system genuinely ran out of memory, and the cause should be sought in your service configuration or in the amount of RAM.
How to confirm OOM Killer actually killed the process
If a service unexpectedly went down without a clear error in its own log, check the system journal:
journalctl -k | grep -i "out of memory"
dmesg | grep -i oom
The output will show a line like Out of memory: Killed process 1234 (mysqld) with the PID, process name, and the amount of memory occupied at the moment of the kill. This is the easiest way to distinguish OOM Killer from a process crashing for another reason, such as a segmentation fault.
How to find the process eating memory
Before setting up protection, find the actual memory consumer. A quick way is to sort processes by RAM usage:
ps aux --sort=-%mem | head -n 10
free -h
The free -h command shows total memory, used memory, free memory, and the swap size. Without swap, or with a small one, any load spike — a database backup, a traffic surge — instantly leads to OOM. For a detailed look at configuring swap, see the article on swap on a Linux VPS.
How the kernel picks a victim: oom_score
The kernel assigns every process an oom_score value — the higher it is, the more likely the process gets killed first. You can check the current score like this:
cat /proc/PID/oom_score
The score is affected by the amount of memory used, how long the process has been running, and an explicit oom_score_adj setting, which takes values from -1000 to 1000. A value of -1000 fully excludes a process from being killed, while 1000 makes it the first target.
How to protect an important process from OOM Killer
If your server runs a service that must never be killed under any circumstances, say the main database, lower its kill priority:
echo -900 > /proc/$(pidof mysqld)/oom_score_adj
This change lasts only until the process restarts. To make the setting permanent, add the parameter to the service's systemd unit file:
[Service]
OOMScoreAdjust=-900
After editing, run systemctl daemon-reload and restart the service. By protecting one process, you automatically raise the risk for the others — the kernel will still find someone to kill under a genuine memory shortage.
Prevention: swap, memory limits, and monitoring
A one-time oom_score_adj tweak does not solve a memory shortage — it just shifts the risk to another process. Real prevention looks like this:
- Set up a swap file of at least 1-2 GB to smooth out short-term load spikes.
- Explicitly limit memory for heavy services:
memory_limitin PHP,innodb_buffer_pool_sizein MySQL,-Xmxin Java. - Connect RAM usage monitoring so you can see consumption rising before OOM triggers — see the article on VDS resource monitoring.
- Check the journal with
journalctl -kafter every incident — read more in the article on journalctl and rsyslog. - Under a systemic memory shortage, the right step is to upgrade your VDS plan, not fight the symptoms.
Frequently asked questions
Can OOM Killer trigger even when swap is configured on the server?
Yes, swap only delays the moment it kicks in, it does not rule it out: if load grows faster than the system can page data to swap, or swap is too small for the real peak usage, memory still runs out and the kernel still picks a victim. Swap just lowers how often this happens, not whether it can happen.
If a process's oom_score_adj is lowered to -1000, does that guarantee it will never be killed?
A value of -1000 does fully exclude that process from being picked under the oom_score rules, so it will not be killed. But that does not fix the underlying memory shortage: the kernel will still find another victim among the remaining processes, and once both memory and swap are truly exhausted the system as a whole can start behaving unpredictably.
Is it worth just disabling OOM Killer so it stops touching processes at all?
No, it is a protective mechanism, not a malfunction: without it, a genuine memory exhaustion does not fail gracefully, it freezes the whole system, and recovering then means a manual reboot. The fix is removing the cause of the shortage, not disabling OOM Killer: add swap, set limits on heavy services, and upgrade the plan when the shortage is systemic.
What signs indicate it's time to upgrade the server plan rather than protect individual processes one by one?
If OOM Killer keeps triggering regularly after adding swap, setting memory limits on services, and monitoring usage, rather than firing once during a random load spike, that signals the actual amount of memory is systemically too small for the current workload. Protecting one process at a time then only shifts the risk onto other services instead of removing the shortage.