When your beefy Ryzen 9 system locks up during a simple pacman -Syu, something
is very wrong. Here’s how to stop Baloo, ClamAV, and poor IO scheduling from
hijacking your desktop.
The Problem
Picture this: you’re running system updates on a Ryzen 9 7945HX3D with 62GB of RAM and dual NVMe drives. DKMS starts compiling the nvidia module and suddenly your entire desktop freezes. Mouse cursor? Frozen. Keyboard? Unresponsive. The only option is reaching for the power button.
This should not happen. A modern system with this kind of hardware should handle background compilation without breaking a sweat. Time to investigate.
The Culprits
After some digging, three major offenders emerged:
1. Baloo File Indexer
KDE’s file indexer was the worst offender:
$ balooctl6 status
Total files indexed: 845,512
Files waiting for content indexing: 103,138
Current size of index is 24.27 GiB
Twenty-five gigabytes of index data, with over 100,000 files still queued. Worse, checking mounted filesystems revealed the real problem:
$ mount | grep cifs
//truenas.localdomain/share on /mnt/share type cifs ...
Baloo was trying to index a network share. Every file access over the network was blocking IO and competing with the desktop for resources. Classic.
2. ClamAV Daemon
The antivirus daemon was consuming 1.2GB of RAM just sitting there:
$ systemctl status clamav-daemon
Memory: 1.2G (peak: 2.1G)
On Linux, ClamAV is honestly overkill for a desktop system. It’s designed for mail servers and file shares, not personal workstations where you control what gets executed.
3. Wrong IO Scheduler
Both NVMe drives were using the BFQ scheduler:
$ cat /sys/block/nvme*/queue/scheduler
[bfq]
[bfq]
BFQ is great for HDDs and SATA SSDs where the kernel needs to optimize head movement and queue depth. NVMe drives have their own hardware schedulers with massive parallel queue support. Adding kernel-level scheduling just creates overhead.
The Fixes
Step 1: Kill Baloo
If you don’t use KDE’s file search (and let’s be honest, most terminal users don’t), just disable it:
# Disable the indexer
balooctl6 disable
# Delete the bloated database
rm -rf ~/.local/share/baloo
The config file at ~/.config/baloofilerc will now show:
[Basic Settings]
Indexing-Enabled=false
This persists across reboots. Done.
Step 2: Remove or Throttle ClamAV
Security Consideration: Removing antivirus software is a trade-off between performance and security. While Linux desktops are less targeted than Windows, threats do exist — especially if you download software from untrusted sources, open email attachments, or share files with Windows users. Proceed at your own risk.
For a personal desktop where you’re not scanning incoming mail or shared files, you have a few options:
Option A: Remove ClamAV entirely (at your own risk)
sudo systemctl disable --now clamav-daemon clamav-freshclam
sudo pacman -Rns clamav
Option B: Keep ClamAV but throttle it
If you want to keep real-time protection but prevent it from impacting system responsiveness, create a systemd override:
sudo mkdir -p /etc/systemd/system/clamav-daemon.service.d
sudo tee /etc/systemd/system/clamav-daemon.service.d/override.conf << 'EOF'
[Service]
Nice=19
IOSchedulingClass=idle
IOSchedulingPriority=7
CPUSchedulingPolicy=idle
CPUQuota=30%
MemoryMax=1G
EOF
sudo systemctl daemon-reload
sudo systemctl restart clamav-daemon
This forces ClamAV to only use idle CPU/IO time and caps its resource usage.
Option C: Manual scans only
Disable the daemon but keep the package for on-demand scanning:
sudo systemctl disable --now clamav-daemon clamav-freshclam
# Scan manually when needed:
# clamscan -r /path/to/scan
Alternatives to ClamAV
If you remove ClamAV, consider these complementary security measures:
- Firejail — Sandbox untrusted applications with minimal effort
- AppArmor — Mandatory access control for limiting application capabilities
- USBGuard — Protect against rogue USB devices
- Common sense — Don’t run random binaries from the internet, verify checksums, use official repositories
For most Linux desktop users who stick to official repos and don’t open suspicious attachments, the risk is manageable. But if you’re handling sensitive data or files from untrusted sources, keep some form of scanning available.
Step 3: Fix the IO Scheduler
Create a udev rule to set the correct scheduler per drive type:
sudo tee /etc/udev/rules.d/60-ioschedulers.rules << 'EOF'
# NVMe drives have hardware schedulers - use none
ACTION=="add|change", KERNEL=="nvme[0-9]*n[0-9]*", ATTR{queue/scheduler}="none"
# HDDs benefit from BFQ
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"
# SATA SSDs - none is fine
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="none"
EOF
# Apply immediately
echo none | sudo tee /sys/block/nvme*/queue/scheduler
Step 4: Install ananicy-cpp
This is the real game-changer. Ananicy-cpp automatically adjusts process priorities based on what’s running:
sudo pacman -S ananicy-cpp
yay -S cachyos-ananicy-rules-git # Community rules
sudo systemctl enable --now ananicy-cpp
Now add custom rules. First, demote background tasks that shouldn’t freeze your desktop:
sudo tee /etc/ananicy.d/package-managers.rules << 'EOF'
# Package managers and compilers - lowest priority
{"name": "pacman", "type": "BG_CPUIO"}
{"name": "yay", "type": "BG_CPUIO"}
{"name": "makepkg", "type": "BG_CPUIO"}
{"name": "dkms", "type": "BG_CPUIO"}
{"name": "mkinitcpio", "type": "BG_CPUIO"}
{"name": "gcc", "type": "BG_CPUIO"}
{"name": "cc1", "type": "BG_CPUIO"}
{"name": "cc1plus", "type": "BG_CPUIO"}
{"name": "rustc", "type": "BG_CPUIO"}
{"name": "cargo", "type": "BG_CPUIO"}
{"name": "ninja", "type": "BG_CPUIO"}
{"name": "make", "type": "BG_CPUIO"}
# Coredump processing - can churn through 100MB+ dumps
{"name": "systemd-coredump", "type": "BG_CPUIO"}
{"name": "coredumpctl", "type": "BG_CPUIO"}
EOF
The BG_CPUIO type sets nice=16, ioclass=idle, and sched=idle. These
processes will only get CPU and disk time when nothing else needs it.
Next, boost interactive desktop applications that need to stay responsive:
sudo tee /etc/ananicy.d/99-desktop-priority.rules << 'EOF'
# Desktop apps that need high priority for responsiveness
# Terminal emulators
{"name": "warp", "type": "LowLatency_RT"}
{"name": "kitty", "type": "LowLatency_RT"}
{"name": "alacritty", "type": "LowLatency_RT"}
# Plasma desktop - boost higher than defaults
{"name": "plasmashell", "nice": -5, "ioclass": "best-effort", "ionice": 0, "latency_nice": -5}
# Browsers - boost for snappier UI
{"name": "vivaldi-bin", "nice": -3, "ioclass": "best-effort", "ionice": 2, "latency_nice": -3}
{"name": "firefox", "nice": -3, "ioclass": "best-effort", "ionice": 2, "latency_nice": -3}
EOF
The LowLatency_RT type sets nice=-12 — these apps get CPU priority over
almost everything else. The 99- prefix ensures this file loads last and
overrides any conflicting defaults.
Step 5: Tune VM Dirty Page Handling
The kernel’s default dirty page settings are tuned for servers, not desktops. With 62GB of RAM, the defaults would allow gigabytes of dirty pages to accumulate before flushing — causing massive IO storms that freeze everything.
sudo tee /etc/sysctl.d/99-desktop-responsiveness.conf << 'EOF'
# Use absolute byte limits instead of percentages
vm.dirty_ratio = 0
vm.dirty_background_ratio = 0
# Start background writeback at 256MB
vm.dirty_background_bytes = 268435456
# Force sync at 1GB max
vm.dirty_bytes = 1073741824
# Flush dirty pages faster
vm.dirty_expire_centisecs = 1000
vm.dirty_writeback_centisecs = 100
# Keep 256MB always free
vm.min_free_kbytes = 262144
# Desktop-friendly swappiness
vm.swappiness = 10
vm.vfs_cache_pressure = 50
EOF
sudo sysctl --system
The Results
| Before | After |
|---|---|
| System freezes during updates | Desktop stays responsive |
| 25GB Baloo database | 0 bytes |
| 1.2GB ClamAV RAM usage | 0 bytes |
| BFQ overhead on NVMe | Direct hardware scheduling |
| Compilation starves desktop | Compilation yields to UI |
| Coredump processing freezes system | Runs at idle priority |
| All processes equal priority | Desktop apps prioritized |
The final priority hierarchy looks like this:
| Process | Nice | Notes |
|---|---|---|
| warp, kitty, kwin | -12 | LowLatency_RT — always responsive |
| plasmashell | -5 | Boosted from default -1 |
| vivaldi, firefox | -3 | Snappier than default |
| normal processes | 0 | Default |
| pacman, dkms, gcc | +16 | BG_CPUIO — idle only |
| systemd-coredump | +16 | Won’t freeze on crash dumps |
DKMS can now compile nvidia modules while I continue working. Package updates run in the background without the mouse cursor freezing. Even when an app crashes and generates a 100MB+ coredump, the desktop stays smooth. The system finally behaves like it should on modern hardware.
Diagnostic Commands
When things go wrong, these help identify the culprit:
# What's causing IO wait?
iotop -oPa
# System IO-bound?
vmstat 1 5
# Processes stuck in disk wait (D state)?
ps auxf | grep " D "
# Current dirty page status
grep -E "^(Dirty|Writeback):" /proc/meminfo
The Takeaway
A powerful system shouldn’t freeze during routine operations. The defaults in most Linux distributions are tuned for servers or general compatibility, not desktop responsiveness. A few targeted tweaks — killing unnecessary indexers, fixing IO schedulers, and prioritizing interactive processes — make all the difference.
No more hard resets during system updates :^)