Fix "Out of memory: Killed process" (Linux OOM killer)

Quick fix

Confirm the kill and see what was using memory, then give the system headroom (swap or zram) and cap the offender.

journalctl -k -b | grep -iE 'out of memory|oom-kill|invoked oom-killer'
journalctl -b -u systemd-oomd
free -h
swapon --show

The kernel log line looks like this:

Out of memory: Killed process 48211 (java) total-vm:12582912kB, anon-rss:7340032kB, file-rss:0kB, shmem-rss:0kB, UID:1000 pgtables:15200kB oom_score_adj:0
oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/user.slice/...,task=java,pid=48211,uid=1000

In your terminal you only see Killed, and the exit status is 137.

What the error means

The kernel ran out of RAM and swap it could reclaim, so the OOM (out-of-memory) killer chose a process with the highest oom_score (roughly, the largest memory user) and sent it SIGKILL to keep the system alive. The killed process is often the culprit, but not always: it is the biggest one, which may be a victim of something else growing. The line also tells you whether the limit was global (global_oom) or a cgroup limit (CONSTRAINT_MEMCG), such as a container or a systemd service with MemoryMax=.

Find what used the memory

Before the kill, the kernel prints a table of every process and its memory. Read the whole report:

journalctl -k -b -1 | grep -B5 -A40 'invoked oom-killer'   # previous boot
sudo dmesg -T | grep -A40 'invoked oom-killer'              # current boot

The rss column (in 4 KiB pages) shows who held memory. While the problem is happening, sort live processes by memory:

ps aux --sort=-rss | head -10
systemd-cgtop -m        # memory per service / cgroup

The journalctl cheat sheet covers filtering by boot and time.

Cause 1: the workload needs more memory than you have

Compiling large projects with many parallel jobs, running VMs, large databases, browsers with hundreds of tabs, or loading big datasets. Fixes in order of effort:

  • Reduce parallelism: make -j4 instead of -j$(nproc); each compiler job can use 1–2 GB.
  • Configure the application's own limit: JVM -Xmx, PostgreSQL shared_buffers/work_mem, Node --max-old-space-size.
  • Add swap or zram (below) so short spikes do not kill anything.
  • Add RAM.

Cause 2: no swap, or too little

With no swap at all, any spike above physical RAM triggers the OOM killer immediately. Check with swapon --show and free -h. Add a swap file (ext4/XFS):

sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap defaults 0 0' | sudo tee -a /etc/fstab

On Btrfs, create it with sudo btrfs filesystem mkswapfile --size 4G /swapfile so copy-on-write is disabled. Fedora already uses zram swap by default (zram-generator); on Debian, Ubuntu and Arch you can install zram-tools or systemd-zram-generator to get compressed in-RAM swap, which helps a lot on low-memory machines.

Cause 3: a memory leak

If a process's RSS grows steadily over hours or days until it is killed, it leaks. Watch it:

watch -n 10 'ps -o pid,rss,cmd -p 48211'

Update the application first, since leaks are commonly fixed upstream. For a service you cannot fix quickly, cap it and let systemd restart it, so the leak kills only that service:

sudo systemctl edit myapp.service
# add:
[Service]
MemoryMax=2G
Restart=on-failure

When a service gets OOM-killed, systemctl status shows Result: oom-kill; see Job for X.service failed for reading unit failures and systemd basics for drop-in overrides.

Cause 4: a container or cgroup limit

If the log says Memory cgroup out of memory or CONSTRAINT_MEMCG, the host had RAM but the container or service hit its own limit. Docker reports "OOMKilled": true:

docker inspect -f '{{.State.OOMKilled}} {{.HostConfig.Memory}}' mycontainer
docker stats --no-stream

Raise the limit (docker run -m 2g, mem_limit/deploy.resources.limits.memory in Compose, resources.limits.memory in Kubernetes) or reduce what runs inside. See the docker commands cheat sheet.

Cause 5: systemd-oomd killed it, not the kernel

Ubuntu and Fedora enable systemd-oomd, which kills an entire cgroup (for example a terminal tab's scope or an app) when memory pressure or swap usage stays high for a while. There is no "Out of memory" kernel line in that case; check:

journalctl -b -u systemd-oomd
oomctl

Example output:

systemd-oomd[812]: Killed /user.slice/user-1000.slice/[email protected]/app.slice/app-gnome-code-4471.scope due to memory pressure for /user.slice/... being 74.21% > 50.00% for > 20s with reclaim activity

If it is too aggressive for your workload, the right fix is still more memory or swap. You can tune thresholds with systemctl edit [email protected] (ManagedOOMMemoryPressureLimit=) rather than disabling the daemon.

Protecting important processes

You can steer the OOM killer away from critical services. Set OOMScoreAdjust=-500 in the unit's [Service] section, or temporarily with echo -500 | sudo tee /proc/PID/oom_score_adj. Use -1000 (never kill) only for things like sshd on a server, because if everything is protected the kernel has nothing to kill. Do not set vm.overcommit_memory=2 without understanding it: many programs fail to start under strict overcommit.

Distro-specific notes

  • Ubuntu 26.04 / 24.04: systemd-oomd is enabled on desktop installs; a swap file at /swap.img is created by the installer.
  • Fedora: zram swap plus systemd-oomd by default; add a disk swap file if you hibernate or run very large jobs.
  • Debian: no oomd by default; the installer creates a swap partition with guided partitioning.
  • Arch: no swap unless you created it; earlyoom or systemd-oomd can be enabled manually.

How to prevent it

  • Always have some swap or zram, even on machines with plenty of RAM.
  • Give services a MemoryMax= and containers a memory limit, so one leak cannot take the host down.
  • Monitor memory and swap usage, and alert on rising swap use, which comes before OOM kills.
  • If programs crash with a segfault rather than being killed, that is a different problem: see Segmentation fault (core dumped).

Frequently asked questions

How do I know if the OOM killer killed my process?

Run journalctl -k | grep -iE 'out of memory|oom-kill' or sudo dmesg -T | grep -i oom. In a shell the process just prints Killed and exits with status 137 (128 + SIGKILL).

Should I disable the OOM killer?

No. Without it the kernel can only hang or panic when memory runs out. Fix the memory usage, add swap, or protect specific processes with OOMScoreAdjust= instead.

What is systemd-oomd and why did it kill my app?

systemd-oomd is a userspace daemon on Ubuntu and Fedora that kills a whole cgroup under sustained memory pressure, before the kernel OOM killer would. Its kills are logged by systemd-oomd in the journal, not in dmesg.

How much swap do I need?

For desktops, a few gigabytes of swap or zram is enough to absorb spikes; for hibernation you need at least as much swap as RAM. Servers often use a small swap so pressure is visible before kills happen.

Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.