Fixing a Slow BTRFS Root Partition on Manjaro

Disclaimer: This article was written with the help of an AI assistant (Claude by Anthropic), based on a real troubleshooting session. Commands and steps were verified during that session, but always read what a command does before running it as root, and adapt the steps to your own system.

A practical guide to diagnosing and fixing the most common cause of file-copy lag on Manjaro installs that use BTRFS (the default).

The Symptom

Your system feels fine in normal use, but copying files to the root partition causes long stalls, the cursor freezes, or the whole desktop feels sluggish until the copy finishes. You’re on an SSD, so it shouldn’t be slow.

The Likely Cause

BTRFS allocates disk space in chunks — 1 GiB blocks for data, 256 MiB for metadata — before actually filling them with files. Over time, especially with Timeshift snapshots pinning old data, the filesystem can end up with every byte of the device assigned to a chunk, even if those chunks are only half-full. When that happens, BTRFS can’t allocate fresh chunks for new writes and has to hunt for free space inside existing ones. The result: severe write lag.

The diagnostic number that reveals this is “Device unallocated” in btrfs filesystem usage. On a healthy system it should be several GiB. If it’s down to a few MiB, you’ve found your problem.

Step 1 — Diagnose

Run these two commands and inspect the output:

sudo btrfs subvolume list /
sudo btrfs filesystem usage /

Look for:

Also confirm TRIM is running:

systemctl status fstrim.timer

It should be active (waiting) with a weekly trigger. If not, enable it:

sudo systemctl enable --now fstrim.timer

Step 2 — Free Actual Space

Balance can’t help if there’s no real space to reclaim. Free space first.

Delete Old Timeshift Snapshots

Use the Timeshift GUI, or list and delete from the CLI:

sudo timeshift --list
sudo timeshift --delete --snapshot 'YYYY-MM-DD_HH-MM-SS'

Keep the two most recent snapshots; delete the rest. Don’t delete Timeshift’s snapshots with btrfs subvolume delete directly — let Timeshift manage them so its database stays consistent.

Clean the Pacman Cache

This is the single biggest space hog on most Manjaro systems.

The paccache tool gives the most control, but it lives in the pacman-contrib package, which isn’t installed by default. Install it once:

sudo pacman -S pacman-contrib

Then:

# Keep only the latest version of each installed package
sudo paccache -rk1

# Remove all cached versions of uninstalled packages
sudo paccache -ruk0

If you’d rather not install pacman-contrib, plain pacman can do a coarser cleanup:

sudo pacman -Sc    # remove cache for packages not currently installed (prompts)
sudo pacman -Scc   # remove ALL cached packages, including for installed ones

paccache -rk1 keeps the latest cached version of each package (useful for downgrades). pacman -Sc keeps cached versions only for currently-installed packages. pacman -Scc keeps nothing.

Trim Journal Logs

sudo journalctl --vacuum-size=200M

Find Other Big Offenders

du -sh ~/.cache ~/.local/share/Trash ~/Downloads 2>/dev/null
sudo du -h -d 1 /var 2>/dev/null | sort -h | tail

Browser caches, old downloads, and /var/log are common culprits.

Step 3 — Verify Space Came Back

Re-run:

sudo btrfs filesystem usage /

Check Device unallocated. If it’s still near zero, the data you “freed” was still being pinned by a snapshot — go back and delete more snapshots.

Step 4 — Balance to Reclaim Chunks

Once you have real free space, run a balance to consolidate partly-full chunks and return them to the unallocated pool:

sudo btrfs balance start -dusage=50 -musage=50 /

This rewrites data and metadata chunks that are less than 50% full, packing them tighter. It can take 10-30 minutes; the system stays usable during the process but will be slow.

If balance complains about lack of space, ramp up gradually:

sudo btrfs balance start -dusage=10 /
sudo btrfs balance start -dusage=25 /
sudo btrfs balance start -dusage=50 /

Step 5 — Confirm the Fix

After the balance finishes:

sudo btrfs filesystem usage /

You want to see:

Copy a large file to root as a real-world test. The lag should be gone.

Preventing Recurrence

Three habits keep this from coming back:

  1. Tighten Timeshift retention. In the Timeshift GUI, set something like 3 daily / 2 weekly / 1 monthly. The defaults accumulate too many snapshots, and BTRFS punishes you for it.
  2. Clean the pacman cache periodically. Add a monthly calendar reminder. With pacman-contrib installed:
    sudo paccache -rk2
    
    Or without it:
    sudo pacman -Sc
    
  3. Watch Device unallocated as a health metric. Check it every few months. If it drops below ~5 GiB, take action before you hit the wall.

Key Reference Commands

Task Command
Inspect filesystem usage sudo btrfs filesystem usage /
List subvolumes/snapshots sudo btrfs subvolume list /
List Timeshift snapshots sudo timeshift --list
Delete a Timeshift snapshot sudo timeshift --delete --snapshot 'NAME'
Clean pacman cache (with pacman-contrib) sudo paccache -rk1
Clean pacman cache (built-in) sudo pacman -Sc
Trim journal logs sudo journalctl --vacuum-size=200M
Balance partly-full chunks sudo btrfs balance start -dusage=50 -musage=50 /
Manual TRIM sudo fstrim -v /
Check TRIM timer systemctl status fstrim.timer

When This Isn’t the Problem

If Device unallocated was already healthy (several GiB) and writes are still slow, look elsewhere: