Open-source project
facebookincubator/oomd avatar
facebookincubator/oomd

oomd: catching memory crises in Linux userspace before the kernel has to

A userspace out-of-memory killer

2,053 stars162 forksC++GPL-2.0

At a glance

What is it?
oomd is a userspace daemon that uses PSI and cgroupv2 to detect and act on memory pressure before the Linux kernel OOM killer runs; it requires both features to be active in the kernel.
Who is it for?
oomd fits Linux production hosts that run cgroupv2 and want to stop the kernel's slow-path OOM handler from locking a host for minutes at a time. Systems without PSI or that still use cgroup v1 cannot run it, and confirming both before installation is work the documentation leaves to the operator.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The kernel OOM killer's slow path: unbounded swap and cache eviction

Linux allows memory overcommitment by default. When malloc(2) returns a pointer, the kernel does not allocate physical memory immediately; it defers that cost until the process reads or writes the promised memory. On a host that has overcommitted, that deferral eventually fails. At the point where physical memory is gone, the kernel must recover. Its recovery involves paging in and out of disk and evicting the page cache for an unbounded period before any process is killed. Kernel-side configuration for choosing which processes to protect is possible but inflexible and complicated to get right.

oomd is a daemon that acts before that kernel path is reached. It monitors memory pressure continuously and kills processes on its own terms before the kernel has to. At Facebook, 30-minute host lockups caused by kernel OOM events disappeared after the daemon was deployed. The kernel's built-in OOM handler remains the fallback when oomd is absent or when a condition falls outside its configured rules. The difference in approach is the timing: oomd targets early intervention; the kernel targets last-resort recovery after things have already gone wrong. Time spent livelocked in kernel space is the cost oomd aims to avoid.

PSI measures waiting time; cgroupv2 maps it to specific workloads

oomd relies on two kernel features that must both be present: Pressure Stall Information and cgroupv2. PSI measures how much time tasks spend stalled waiting for memory rather than doing useful work. It is the signal oomd reads to gauge whether the system is heading toward an out-of-memory event. cgroupv2 provides the hierarchical process accounting that lets oomd attribute pressure to a specific cgroup and take action against that cgroup's processes rather than making a system-wide kill decision.

PSI is a Linux kernel feature that measures memory stall time; a host where PSI is not active has no pressure data for oomd to read. cgroupv2 is a separate adoption question: many production Linux systems still rely on the legacy cgroup v1 hierarchy, and oomd has no documented compatibility mode for v1. The README gives no diagnostic command for verifying that either feature is active on a given host. A host that has PSI disabled in its kernel build provides no signal for oomd to act on, and a host that mounts cgroup v1 rather than cgroupv2 has no hierarchy oomd can work with. Both conditions need to be confirmed before installation, and that confirmation is left entirely to the operator. Checking /proc/pressure for PSI output and examining the cgroup mount type are the standard verification steps, but oomd's documentation does not describe either of those checks.

Installing from packages on Debian, Ubuntu and Fedora

On Debian 11 or later, and Ubuntu 20.04 or later, the package is available through apt:

bash
apt install oomd

Fedora packages oomd in its official repositories. Installation on Fedora requires two commands: one for the package and one to enable and start the service:

bash
sudo dnf install oomd
sudo systemctl enable --now oomd.service

The Debian section of the README omits a systemctl step that the Fedora section includes. Whether the apt install triggers automatic service activation on Debian or Ubuntu, the README does not say. Anyone installing on those distributions should verify that the service is running after the package install completes rather than assuming activation happens automatically.

Building from source requires meson, jsoncpp and a C++20 compiler

Where a distribution package is not available, two dependencies are mandatory: meson as the build system and jsoncpp for configuration parsing. libsystemd is optional. The compiler must support C++20. The build sequence from the repository is:

bash
git clone https://github.com/facebookincubator/oomd
cd oomd
meson build && ninja -C build
cd build && sudo ninja install

Running the test suite requires gtest and gmock. When meson detects those libraries during configuration, it generates test build rules automatically. The test invocation is:

bash
ninja test -C build

The README does not describe what a passing run looks like, how many tests exist, or what a failure typically means. Tests run before the install step, so a failure can be caught before the binary is placed on the system.

After installation, `oomd --list-plugins` on the built binary shows which plugins are compiled into that particular build. The default meson build includes the public plugin set, but the exact contents depend on the source revision compiled.

The plugin architecture: policy lives outside the daemon core

oomd does not embed a fixed definition of what makes a process worth killing. A plugin system controls that decision, and writing custom plugins is explicitly encouraged. By default, corrective action means killing offending processes, but what triggers a kill is defined through plugin configuration rather than hard-coded thresholds. This design allows each cgroup to have its own protection rules: a latency-sensitive web process and a background batch job can each have a plugin applying different pressure thresholds and different responses.

Custom plugins require the project's plugin API. docs/writing_a_plugin.md in the repository is a tutorial for that process. Once installed, `oomd --list-plugins` on the binary lists which plugins are available in that build. A build that does not include a specific plugin provides no corrective action for the cases that plugin covers, so verifying the plugin list after any new install is part of a setup workflow that depends on non-default behavior.

Deploying oomd without reading docs/core_plugins.md means accepting the default plugin set without understanding its thresholds. The default action is a kill, and on a host where no plugin configuration exists, that kill targets whatever process the default heuristic selects. For workloads with strict ordering requirements, the configuration reference in docs/configuration.md is the right starting point before any first deployment.

Documentation structure: four files beyond the README

Four files under docs/ each cover a distinct part of deployment. configuration.md is where to find the format oomd expects and the examples that show how each field changes daemon behavior. core_plugins.md names each plugin in the default build alongside the threshold it monitors. production_setup.md covers decisions the default install does not address, including how oomd fits into a host's broader process management. writing_a_plugin.md takes the reader from an empty file to a working plugin, covering the API surface the project exposes to custom code.

None of those four files is summarized in the README body. Every link points to the file itself, so there is no abbreviated version to read in place of opening the file. For a first deployment, configuration.md and production_setup.md together describe what the system expects to find and how oomd should be positioned relative to the rest of the host's process management. A team that skips those two files and deploys with defaults is running oomd with no explicit configuration, which means the daemon applies its default plugin thresholds across all cgroups on the host.

The man/ directory at the repository root also appears in the top-level listing, which points to manual pages being present. The README does not describe their contents or which commands they cover. CONTRIBUTING.md and CODE_OF_CONDUCT.md are both present at the repository root.

Where oomd cannot help: cgroup v1 systems and kernels without PSI

oomd is Linux-specific. PSI and cgroupv2 are Linux kernel features with no equivalent on macOS, Windows or other non-Linux systems. The README addresses Debian, Ubuntu and Fedora by name and no other platforms. Any environment without direct access to a cgroupv2 hierarchy is outside what oomd can address.

The tool acts on processes at the moment it detects pressure. It does not document a rollback mechanism for restoring application state after a kill, a swap configuration guide, or kernel parameter tuning. docs/production_setup.md carries the production-specific guidance that the README does not inline, and that file is the one the README explicitly recommends for production setup.

For systems that want a userspace OOM handler but run cgroup v1 rather than cgroupv2, oomd is the wrong choice. The dependency on cgroupv2 is structural, and no partial mode exists for v1 systems. A host in the middle of a cgroup migration needs to complete that migration before oomd can be deployed usefully.

The top-level listing includes a vcs_tagger.sh script. The most recent tag in the repository is v0.5.0 from 2021-06-23, while the last push was on 2026-09-09, meaning distribution packages may contain code not covered by any documentation in the repository.

Editorial conclusion

oomd fits Linux production hosts that run cgroupv2 and want to stop the kernel's slow-path OOM handler from locking a host for minutes at a time. Systems without PSI or that still use cgroup v1 cannot run it, and confirming both before installation is work the documentation leaves to the operator. The last tagged release is v0.5.0 from 2021-06-23 while the last push was 2026-09-09, a gap no documentation covers, and PSI requires kernel 4.20 or newer. Before any production rollout, read docs/production_setup.md and run oomd --list-plugins on the installed binary to confirm which plugins the build contains.

Frequently asked questions

What does oomd require to function on Linux?

oomd requires Pressure Stall Information and cgroupv2 as the active cgroup hierarchy. Both must be present; the README documents no fallback for a system that lacks either.

How does oomd decide which process to kill?

oomd uses a plugin system to define which processes to target and what action to take. The default action is killing offending processes, but each cgroup can have its own plugin configuration. The core plugins are documented in docs/core_plugins.md.

Does oomd replace the Linux kernel OOM killer?

oomd acts in userspace before the kernel OOM killer runs, so the kernel's own OOM handler rarely needs to intervene on a system running oomd. The project's stated goal is preventing the slow-path kernel response rather than running alongside it.

How do I install oomd on Ubuntu or Fedora?

On Ubuntu 20.04 or later, apt install oomd installs the package. On Fedora, the commands are sudo dnf install oomd followed by sudo systemctl enable --now oomd.service to enable and start the service.

Can I write custom plugins for oomd?

Writing custom plugins is explicitly encouraged. docs/writing_a_plugin.md in the repository is a tutorial for that process, and docs/core_plugins.md is a quick reference for the plugins that ship with oomd by default.

Official sources

  1. facebookincubator/oomd on GitHub
  2. Issues
  3. License: GPL-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/facebookincubator-oomd.svg)](https://hysenlabs.com/projects/facebookincubator-oomd)