SysadminNews

Fedora CoreOS Turns On systemd-oomd and zRAM Swap

On this page
  1. Why CoreOS was the variant that could not have this
  2. What systemd-oomd changes about how a node fails
  3. Reading the zram trade honestly
  4. What we would check before F45 arrives
  5. Sources and further reading

Fedora CoreOS will enable systemd-oomd.service and swap on zram by default, starting with Fedora Linux 45. The Fedora Engineering and Steering Committee approved the change unanimously under ticket 3661, and Phoronix reported it on August 10, 2026. The point that deserves your attention is not the feature itself, since every other Fedora variant has shipped both for years. It is the scope. The change proposal states plainly that it affects all nodes, existing running ones included, and warns about applications that do not accept swap by default. If you run Kubernetes on CoreOS, that sentence is the whole story.

The short answer

Fedora CoreOS will enable systemd-oomd.service and swap on zram by default from Fedora Linux 45, aligning it with the other Fedora variants. FESCo approved the change under ticket 3661. It was held back for years because the kubelet refused to run on a node with swap, and it is unblocked now that Kubernetes supports node swap behind explicit configuration. The proposal states the change reaches existing running nodes, not only new installs.

F45the Fedora release where CoreOS gets both defaults
#3661the FESCo ticket, approved unanimously
allnodes affected, existing running ones included
Answer card: the Fedora Engineering and Steering Committee approved ticket 3661 to enable systemd-oomd.service and swap on zram by default in Fedora CoreOS starting with Fedora Linux 45, aligning CoreOS with other Fedora variants, with the change affecting existing running nodes as well as new installs and requiring attention for Kubernetes clusters.
The approved change in one card. Sources: the Fedora Project Wiki change proposal and Phoronix, August 10, 2026. PNG

Most default changes in a distribution are worth a line in the release notes and nothing more. This one is worth twenty minutes of your afternoon, and the reason is a single sentence in the change proposal rather than the feature it describes.

Fedora CoreOS is enabling systemd-oomd.service and swap on zram by default with Fedora Linux 45. Both have shipped on Workstation and the other variants for years, so the feature itself is not news. What the proposal adds is scope: the change affects all nodes, existing running ones included, and it explicitly tells you to take care of applications that will not accept swap as default behaviour. Kubernetes is named.

The Fedora Engineering and Steering Committee approved it unanimously under ticket 3661. Phoronix reported it on August 10, 2026. The change is owned by Nemric and jbtrystram, and the wiki page was last touched on July 28, 2026.

Why CoreOS was the variant that could not have this

The kubelet used to refuse to start on a node with swap enabled. That was not caution, it was a correctness position.

Kubernetes memory accounting treats a pod's memory limit as a hard physical ceiling, and the scheduler places work on nodes based on that model. Swap breaks the model in a specific way: a container that exceeds its working set can spill into swap and carry on running very slowly, instead of being killed at the limit. The limit stops being a limit and becomes a performance cliff the scheduler cannot see. On a node running one workload that is merely unpleasant. On a shared node it means a noisy neighbour degrades everyone while every dashboard reports the cluster as healthy.

Kubernetes has since gained node swap support behind explicit kubelet configuration, which is what made this proposal possible. The change owners report running it with failSwapOn set to false and swap behaviour constrained. That is the important detail for anyone about to inherit this default: it works, but it works because somebody configured it, not because it is safe by accident.

Terminal session checking the new defaults on a Fedora CoreOS node: zramctl showing a compressed zram0 device in use as swap, swapon listing it with high priority, systemctl is-enabled systemd-oomd returning enabled, and a read of the memory pressure stall information file.
The four commands that tell you where a node stands. Example output, not a capture of a specific machine. PNG

What systemd-oomd changes about how a node fails

The kernel OOM killer is a last resort and behaves like one. It runs when an allocation has already failed, which on a memory starved machine happens after several minutes of thrashing during which the node is functionally unavailable while technically alive. Then it picks a process by heuristic and kills it. Anyone who has watched a database get selected because it had the largest resident set knows how that goes.

systemd-oomd runs earlier and on a different signal. It reads pressure stall information, the kernel PSI counters that report how much time tasks spend stalled waiting on memory, and when a cgroup crosses a configured pressure threshold for a configured duration it kills that whole cgroup. Killing the cgroup rather than a process matters, because a workload is usually several processes and taking one of them leaves you with a broken half.

The behaviour you get is a node that sheds one workload quickly instead of a node that grinds for ten minutes and then removes something arbitrary. That is better on almost every axis. It is also a change in when your alerts fire and what they say, which is the part that surprises people.

Reading the zram trade honestly

A zram device is a block device backed by compressed memory. Swapping to it costs CPU for compression and returns capacity, with no disk involved, no write amplification on the SSD, and latency measured against RAM rather than storage.

The limit is structural and worth stating plainly: the swap lives in the memory you were short of. Compression on real workloads commonly lands somewhere around two or three to one, so the effect is that a machine holds noticeably more resident data before pressure builds. It is headroom, not the capacity a disk backed swap file gives you. On a node whose failure mode is a brief allocation spike, headroom is exactly the right medicine. On a node that is simply undersized for what it runs, it defers the problem by minutes.

Fedora's shipped zram configuration lives in the usual systemd generator paths, and the distribution scaled the default device to the size of RAM capped at 8 GiB in an earlier change. Check the value on your own image rather than assuming, since variants have historically differed.

What we would check before F45 arrives

Start with the kubelet configuration, because that is where an implicit protection is about to disappear. If your config does not explicitly state failSwapOn and a swap behaviour, you have been relying on the kubelet's old refusal to start as a safety net. That is not a configuration decision, it is an accident that happened to protect you, and it stops protecting you when the node comes back from an upgrade with swap enabled and a kubelet willing to tolerate it.

Then look at workloads whose memory limits were tuned on the assumption that exceeding them means immediate death. Batch jobs and anything with a leak that was previously self correcting through the OOM killer are the candidates. Under swap they degrade instead, which is usually worse than dying because it is harder to notice.

Finally, check whether you graph PSI memory pressure at all. systemd-oomd is about to make decisions on a signal most teams do not currently collect, and the first time it acts you will want the history. Reading /proc/pressure/memory is enough to start; getting it into whatever you already use for metrics is an hour of work that pays for itself the first time a node sheds a pod at three in the morning.

If you want to test the behaviour deliberately rather than discovering it, we looked at a debugfs interface for aiming memory pressure at a Linux system recently, which is a better way to find out than production. And for where the cluster side is heading, our note on Kubernetes 1.37 and containerd 2 covers the release this will meet.

Sources and further reading

Frequently asked questions

What does systemd-oomd do that the kernel OOM killer does not?

It acts earlier and it acts on cgroups rather than processes. The kernel OOM killer runs when allocation has already failed, which is late: by then the machine has usually spent minutes thrashing and is functionally unavailable even though nothing has technically died. systemd-oomd watches pressure stall information, the kernel PSI metrics that report how much time tasks spend waiting on memory, and when a cgroup crosses a configured pressure threshold it kills the whole cgroup. The practical difference on a server is between a node that degrades for ten minutes and then kills a random process, and a node that sheds one workload quickly and keeps serving.

Why did Fedora CoreOS hold this back when other variants shipped it years ago?

Kubernetes. The kubelet historically refused to start on a node with swap enabled, which is what the failSwapOn setting exists to control, because the scheduler's memory accounting assumes a pod's memory limit is a hard physical ceiling. Swap breaks that assumption: a container over its working set can spill to swap and keep running slowly rather than being killed, which makes limits soft in a way the scheduler does not model. Kubernetes has since gained node swap support behind explicit kubelet configuration, which is what unblocked the proposal. The change owners note they run it successfully with failSwapOn set to false and swap behaviour limited.

Does zram swap actually help, or is it swap with extra steps?

It is a different trade and worth understanding as one. A zram device is a block device backed by compressed RAM, so swapping to it costs CPU cycles for compression and gives back memory capacity, with no disk involved and no write amplification on your SSD. Typical compression on real workloads runs somewhere around two or three to one, which means a machine can hold meaningfully more resident data before pressure builds. What it cannot do is survive the memory being gone, because the swap lives in the memory you were short of. It buys headroom and latency, not capacity in the way a disk swap file does.

How do I opt out on a node where this would be wrong?

Through Butane and Ignition like everything else on CoreOS, and it is worth writing the config before the upgrade rather than after. The zram device is created by a systemd generator that reads its configuration from the usual systemd paths, so a drop in that overrides the shipped size setting removes the device, and systemd-oomd is an ordinary unit that can be masked. Put both in the machine config that provisions the node so the state is declared rather than applied by hand. Check the Fedora CoreOS documentation for the exact file names in the release you are running, because generator configuration paths are the sort of detail that moves.

What should I check on my nodes before Fedora 45 reaches them?

Three things. Whether your kubelet configuration explicitly sets failSwapOn and a swap behaviour, because relying on the old refuse to start default is not a configuration, it is an accident that used to protect you. Whether any workload on the node has memory limits tuned against the assumption that exceeding them means immediate death, since swap makes that a slow degrade instead. And whether you have alerting on PSI memory pressure at all, because systemd-oomd will start making decisions based on a signal most teams do not currently graph.