OOM Kills Are Silent — Here Is How to Get Alerted Before They Become Outages
The worst kind of production incident starts with a mystery: your service is dead, there is no error in your application log, no deploy happened, and the only traceback you will ever find is a single line in the kernel log: Out of memory: Killed process 12847 (node). By the time you find it, your users found it first.
This guide covers why OOM kills evade most monitoring setups, and how to get a real alert — in Slack, Discord, or on your phone — the moment the kernel reaper picks your process.
Why the OOM killer does not warn you
Linux handles memory exhaustion brutally and silently. When the system runs out of allocatable memory, the kernel scores every process, picks the most expensive one, and sends SIGKILL. There is no graceful shutdown, no stack trace in your app's log, no exception to forward to Sentry. Your process simply ceases to exist.
The only record lives in dmesg and the systemd journal — places almost nobody watches automatically. Meanwhile:
- Your external uptime check still sees green until the load balancer drains the dead backend or the last retry times out.
- Your application monitoring (APM, error tracking) saw nothing — the process never got a chance to log.
- Your metrics dashboard shows a gap, but gaps look like many things and nobody pages on a gap.
The result: OOM kills routinely sit undetected for minutes to hours, especially on low-traffic services that only get probed from the outside.
The early-warning signals that exist
An OOM kill is the end of a failure story, not the beginning. A host agent sees the buildup:
- Memory headroom shrinking — the interval between "80% used" and "kernel starts killing" can be hours. That is your real alert window.
- RSS growth of the target process — a leak shows up as steady, monotonic growth long before pressure becomes critical.
- The kill itself — kernel log entries like
oom-kill,Out of memory, andMemory cgroup out of memoryare deterministic signals, not heuristics. - The aftermath — systemd restart counters increment, the unit enters failed or activating state, the process disappears or respawns with a fresh PID.
Catch any of these and you convert "silent kill" into "paged before customers noticed".
Wiring it up: agent + event rules
With Uptriva's agent the pipeline is short:
- Install the agent on the host — single binary, registers via API token, starts reporting metrics and events.
- Create an event rule for OOM detection: the agent tails kernel events and emits an
oom_killevent with the victim process name and PID. - Set a memory-headroom threshold so you get the warning before the kernel decides — e.g. alert when free memory drops under 10% for more than 5 minutes.
- Route to your contacts — the event flows through the same escalation chains as uptime monitors: Slack channel first, SMS at level two, call at level three if nobody acks.
The practical difference: instead of discovering the OOM kill when you grep dmesg during the postmortem, you get payments-service was OOM-killed (pid 12847) in Slack while the service is still being restarted.
Fixing it is still on you — but now you know
An alert does not stop a memory leak. What it does is give you the which and when to find the why: which process the kernel scored highest, when the growth started, what correlates with it (deploy? traffic spike? cron job?). With memory-headroom alerts you often get days of runway to investigate before the first kill happens at all.
The honest caveat
Host-level OOM visibility requires an agent on the host — containerized or fully managed services where you cannot run one will not produce these events. For those, memory metrics from the provider plus external probes remain the fallback. But anywhere you control the host, there is no excuse for learning about OOM kills from your users.
The Uptriva agent reports OOM kills, process deaths, systemd failures and memory pressure out of the box. Setup is one binary and about two minutes: agent docs.