A process that disappears without an application error may have been terminated by Linux’s out-of-memory (OOM) handling. This can happen even when a VPS appears to have some memory available: the kernel may be responding to a short-lived spike, a container limit, or a workload that cannot reclaim enough memory quickly.
The useful question isn’t just “How much RAM is free?” It’s “What was under pressure, when did it happen, and which process or limit was involved?”
Start with current memory, but don’t stop there
On the affected host, check the broad picture:
free -h
The available column is usually more useful than free. Linux uses otherwise idle memory for caches, which can be reclaimed when applications need it. A small free value alone does not prove the machine is running out of memory.
For a changing view, run:
vmstat 1
In the output, si and so show swap-in and swap-out activity. Sustained nonzero values can indicate memory pressure, though occasional activity isn’t conclusive by itself. The first data row summarizes activity since boot; focus on subsequent rows for the current interval.
To find the largest current consumers:
ps -eo pid,ppid,user,rss,%mem,comm --sort=-rss | head -n 15
RSS is resident memory, shown in kilobytes. It’s useful for spotting large processes, but summing RSS can overcount shared memory, so don’t treat the total as an exact measure of physical memory use. If you need help reading process listings, see how to list processes in Linux.
Check whether the kernel recorded an OOM kill
An OOM kill often leaves a kernel message naming the process and showing memory details. On a system using systemd’s journal, inspect kernel messages from the current boot:
sudo journalctl -k -b --no-pager | grep -i -E 'out of memory|oom-kill|killed process'
If the failure happened before the current boot, search earlier boots if the journal retains them:
sudo journalctl --list-boots
sudo journalctl -k -b -1 --no-pager | grep -i -E 'out of memory|oom-kill|killed process'
The -b -1 option selects the previous boot. Journal retention varies by system, so an empty result doesn’t prove an OOM kill didn’t happen. Logs may have rotated, the journal may not persist across reboots, or another supervisor may have stopped the process. For more ways to filter logs by service and time, see the journalctl guide.
Look for the process name, its PID, and wording such as Killed process. If you find an entry, note its timestamp and compare it with application, deployment, or monitoring logs. A process being killed by the kernel is different from one exiting on its own, crashing, or being stopped by systemd.
Check for a container memory limit
A container can hit its own memory limit while the host still has plenty of RAM. In that case, host-wide free -h may look healthy.
With Docker, inspect the container’s configured limits and recent state:
docker inspect --format '{{.Name}} memory={{.HostConfig.Memory}} state={{.State.OOMKilled}} exit={{.State.ExitCode}}' myapp
A memory value of 0 means no explicit memory limit is set in that container configuration. OOMKilled=true is a useful clue, but inspect the container’s events and application logs too; the exit state alone may not reveal why memory grew.
For a live view of usage and limits, use:
docker stats myapp
If the workload runs under Kubernetes or another container manager, investigate the platform’s resource limits and events rather than relying only on host-level tools. A cgroup can enforce a limit below the total memory available to the machine.
Look for pressure over time
A one-time snapshot can miss the event. If the process is still running, check Linux’s pressure stall information (PSI):
cat /proc/pressure/memory
The some line reports time when at least some tasks were stalled waiting for memory resources; full reports intervals when all non-idle tasks were stalled. The avg10, avg60, and avg300 fields are rolling averages, while total is cumulative stall time in microseconds since boot. PSI can show meaningful pressure even when a quick memory check looks less alarming.
For historical diagnosis, use monitoring that records memory, swap, container limits, and process restarts. Without measurements from the time of the incident, it may be impossible to distinguish a brief spike from a persistent leak after the machine has recovered.
Confirm the service’s restart behavior
A service manager may restart a process after it exits, making the symptom look like a brief outage rather than a stopped process. Check the unit’s recent state and logs:
systemctl status myapp.service
sudo journalctl -u myapp.service --since '1 hour ago' --no-pager
Look for repeated restarts, exit codes, and timestamps that line up with kernel messages. systemctl status is a starting point, not a complete diagnosis; use the service log and the unit’s restart policy to understand what happened. The systemctl status guide explains the state and recent log lines it displays.
What to do after finding the cause
Choose a fix based on the evidence:
- One process grows without a reasonable bound: investigate its workload, caches, queues, or memory leak; restarting it may restore service but won’t fix the underlying growth.
- A container reaches its limit: compare the limit with real workload needs, then adjust it deliberately or reduce the application’s peak usage. Raising a limit without checking host capacity can move the problem to the whole machine.
- Several unrelated services compete for memory: reduce concurrency, move workloads, or add capacity. Swap can provide a buffer, but heavy swapping can make a server unresponsive and is not a substitute for sufficient memory.
- No OOM evidence appears: check application logs, service restart policies, deploy scripts, health checks, and external supervisors. A missing process is not proof of an OOM kill.
A short incident checklist
When a process disappears, collect evidence before restarting everything:
- Record the failure time and affected process or container.
- Check kernel logs for OOM messages around that time.
- Compare host memory with container or service-specific limits.
- Check whether a supervisor restarted the process.
- Preserve application logs and monitoring data before they rotate.
This sequence helps separate host-wide exhaustion from a container limit, a service crash, or an ordinary restart—and points toward a fix that addresses the actual cause.
I'm building SSHFlow — an SSH client that organizes terminals, SFTP, code editing, and server tools into workspaces.
Top comments (0)