Fixing Fedora Freezing Under Load: zram + Disk Swap + earlyoom
Fedora 44 froze completely under heavy load and only a hard power-off recovered it. Here is how I found the root cause (zram-only, no disk swap) and fixed it for good, step by step.
For a while I had been fighting a problem on my Fedora laptop: under heavy load the machine would freeze completely, stop responding to any input, and force me to hold down the power button to shut it off. In this post I walk through how I diagnosed the freeze and how I fixed it for good, showing every command I used. If you are hitting the same problem, you can follow along step by step.
My System / Test Environment#
First, let me share the hardware and software I was working on, because the details of the fix can depend on it:
| Component | Value |
|---|---|
| Model | ASUS Zenbook 14 OLED (UX3405CA) |
| CPU | Intel Core Ultra 9 285H (16 cores) |
| RAM | 32 GB (LPDDR5) |
| Storage | NVMe SSD |
| OS | Fedora Linux 44 (KDE Plasma Desktop) |
| Kernel | 7.1.3-200.fc44.x86_64 |
| Session | Wayland |
| Filesystem | btrfs (LUKS encrypted) |
Note: Most of the commands work on all Fedora versions (and largely on other Linux distributions too). But because my filesystem is btrfs, I used a btrfs-specific method to create the swap file; if you are on ext4, that part is simpler.
What exactly was the problem?#
The symptom was this: when I ran several heavy applications at once (in my case an Android environment + Android Studio + a browser with many tabs + other tools in the background), the system would first slow down, then lock up completely. Even the mouse would not move. Waiting did not help; the only way out was the power button.
At first I wondered “is the hardware failing, is it overheating?” But instead of guessing, I decided to look at the system’s own logs — because Linux writes down the moment it freezes.
Step 1: Finding the root cause (reading the logs from the freeze)#
Linux records the moment it crashes or freezes in the kernel logs. I looked at the last lines of the previous session (the one where it froze) like this:
# Last 40 lines of the previous boot (-b -1)
sudo journalctl -b -1 -n 40 --no-pager
I also specifically searched for any sign of memory exhaustion (OOM = Out Of Memory):
# Was "oom-killer" triggered on the previous boot?
sudo journalctl -b -1 --no-pager | grep -iE 'out of memory|oom-kill|killed process'
The result explained everything. The logs contained these lines:
Free swap = 148kB
Total swap = 8388604kB
systemd-oomd invoked oom-killer
So almost all of my 8 GB swap area was full (only 148 KB left) and RAM had run out too. The system had locked up while trying to find memory. The cause of the freeze was not hardware — it was memory management.
Step 2: Which swap am I using? (checking zram)#
This is where the key detail surfaced. I actually already knew that Fedora uses zram by default — but there is a difference between “knowing” and “checking and seeing it.” To be sure myself, and to show someone with the same problem how to check on their own system, I walk through every step with its command. So where is that “8 GB swap” — on disk, or in RAM? I checked with this command:
# Show active swap areas and their types
swapon --show
The output was:
NAME TYPE SIZE USED PRIO
/dev/zram0 partition 8G ... 100
So my swap was entirely zram. But what is zram?
What is zram? It is a kernel module that reserves a portion of RAM and creates a compressed swap area there. It is much faster than disk because it physically lives in RAM. Fedora has, since version 33 (2020), created swap in zram by default on new installations instead of on disk; in Fedora 34 the size of this area was raised to half of RAM (up to a maximum of 8 GB) — the 8 GB of zram on my system is exactly the result of this default.
You can see zram’s details with:
# zram device size, algorithm, compression ratio
zramctl
This was the root of the problem: my swap was 100% zram, meaning it lived inside RAM. There was no swap on disk at all. That means: when RAM fills up, zram (also being in RAM) fills up too, and there is nowhere left for the data to escape to. That is the point where the system crashes.
The heart of the problem was this: running without a safety net on disk. On a system that has swap on disk, when RAM fills up the overflow spills to disk; the system slows down but stays alive, it does not freeze. In my case, because swap was entirely zram — meaning there was no swap on disk at all — that safety net did not exist.
The plan#
After some research I saw that this is a well-known Fedora behavior. I built a three-layer plan for the fix:
- Add a swap file on disk — the real safety net (like Windows’ pagefile).
- Grow zram a bit — widen the fast layer (8 GB → 12 GB).
- Install earlyoom — a safeguard that automatically kills the greediest process before the system freezes completely.
The logic: when RAM fills up, use the fast zram first, when that fills up let the overflow spill to disk, and in the worst case let earlyoom step in and rescue the system.
Step 3: Adding a swap file on disk (the main fix)#
Because my filesystem is btrfs, you cannot just create a swap file any old way; btrfs requires the swap file to be CoW-disabled (NOCOW), uncompressed, and without holes. Fortunately modern btrfs tools have a command that does this automatically. I created a 16 GB swap file:
# 1) A separate subvolume for swap (to isolate it from snapshots)
sudo btrfs subvolume create /var/swap
# 2) 16 GB swap file — sets NOCOW/compression settings automatically
sudo btrfs filesystem mkswapfile --size 16g /var/swap/swapfile
# 3) Enable swap — priority 10 (must be LOWER than zram's 100)
sudo swapon /var/swap/swapfile --priority 10
Important rule — priority: On Linux, higher priority is used first. zram’s priority is 100. I deliberately gave the disk swap 10 so that disk is not used before zram fills up. That is: RAM first for speed, disk afterward for safety.
To make it permanent (come up automatically on every boot), I added it to /etc/fstab:
# Add a permanent line to fstab
echo '/var/swap/swapfile none swap defaults,pri=10 0 0' | sudo tee -a /etc/fstab
I checked:
swapon --show
NAME TYPE SIZE USED PRIO
/dev/zram0 partition 8G ... 100
/var/swap/swapfile file 16G 0B 10
Now total swap had gone from 8 GB up to 24 GB, and most importantly, there was a disk safety net for RAM to fall back on.
If you are on ext4#
If your disk is not btrfs, the process is simpler:
sudo fallocate -l 16G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile --priority 10
echo '/swapfile none swap defaults,pri=10 0 0' | sudo tee -a /etc/fstab
Step 4: Raising the zram ceiling (8 GB → 12 GB)#
Fedora’s default zram setting is min(ram, 8192), so even though I have 32 GB of RAM it was capping zram at 8 GB. To widen the fast layer a bit, I set it to 12 GB:
# Create/update the zram-generator config file
sudo tee /etc/systemd/zram-generator.conf <<'EOF'
[zram0]
zram-size = min(ram, 12288)
EOF
I also added this to guarantee the zram module loads at boot:
echo zram | sudo tee /etc/modules-load.d/zram.conf
Here I made a mistake (an honest note)#
I wanted to apply this setting immediately, without restarting the computer:
sudo systemctl restart systemd-zram-setup@zram0.service
But the command failed. After some digging I understood why: zram-generator is not designed to be reconfigured on the fly while the system is running — it is designed to kick in only when the computer boots. The clean way to apply a size change is either to manually unload and reload the zram module, or to restart the computer. I chose the cleanest option: I wrote the settings and left the restart for last. In short, not every command worked on the first try; I learned the right way while trying.
Step 5: A last line of defense with earlyoom#
Disk swap solves the freeze, but I wanted one more layer of assurance. earlyoom is a small service that automatically kills the greediest process before memory reaches a critical level:
# Install earlyoom and start it automatically at boot
sudo dnf install -y earlyoom
sudo systemctl enable --now earlyoom
It comes with sensible defaults from Fedora, and the nice part is: it never kills critical system processes (the desktop, systemd, cryptsetup, etc.), targeting first the large, expendable processes like browser tabs.
Step 6: Verifying after the change (the most critical stage)#
Making the settings is not enough; you have to be sure they actually took effect. First I restarted the system, because the real question was: “Will these settings come up automatically at boot?”
After restarting I checked with a single command:
swapon --show
NAME TYPE SIZE USED PRIO
/dev/zram0 partition 12G 0B 100
/var/swap/swapfile file 16G 0B 10
There is the proof: zram came up automatically at 12 GB and the disk swap was active too. Total 27 GB of swap. I also verified the protective services:
systemctl is-active earlyoom systemd-oomd
free -h
Auditing that the setup is correct#
Being a bit paranoid, I also checked that the btrfs swap file really follows the rules. The most important one is the NOCOW flag:
# We need to see the 'C' letter (required for btrfs swap)
sudo lsattr /var/swap/swapfile
---------------C------ /var/swap/swapfile
The C flag was there, so NOCOW was set correctly. Actually the strongest proof is this: the btrfs kernel is very strict — it refuses to open a file as swap if it is CoW-enabled, compressed, or has holes. Since the file shows as active in the swapon --show output, the kernel has already put it through all of those checks.
Result: No more freezing#
After this three-layer setup, instead of freezing and forcing me to hit the power button, the system now slows down briefly under heavy load and then recovers. In summary, what I did:
- Added 16 GB disk swap → an overflow destination when RAM fills up (the main fix).
- Raised zram to 12 GB → a wider fast layer.
- Installed earlyoom → a last-resort emergency brake.
- Total swap went from 8 GB → 27 GB, all persistent.
Quick check commands (summary)#
If you are hitting the same problem, first look at your situation:
swapon --show # Is swap on disk, or in zram?
zramctl # zram details
free -h # RAM and swap usage
sudo journalctl -b -1 | grep -i oom-kill # Was there OOM at the moment of the freeze?
If your swap is entirely zram and there is no swap on disk at all, you are most likely facing the same problem I had. The steps above should do the job.
This post describes a real problem I ran into and the solution I applied. The commands here worked on my system, but every system is different. Before applying them, back up your important data and adapt the commands to your own system (especially if your filesystem is different).
Important: Everything you do is entirely your own responsibility. I am not responsible for any data loss, system failure, or other damage that may occur while applying these steps. If you are not sure what a command does, research it before running it and make sure you have a current backup.