Logo

Btrfs: CoW filesystem for modern Linux

Btrfs: CoW filesystem for modern Linux

Btrfs offers snapshots, subvolumes, compression, RAID, and integrity checking, while staying 100% in the mainline Linux kernel (unlike ZFS). Default filesystem of SUSE, Synology, and Facebook (Meta).

Introduction

Btrfs (B-tree filesystem):

  • Copy-on-Write (CoW) like ZFS
  • Lightweight snapshots and subvolumes
  • Transparent compression (zstd, lzo, zlib)
  • Stable RAID 0/1/10, partial RAID 5/6
  • CRC32C checksums on data + metadata
  • Online resize, defrag, balance, scrub
  • In-place conversion from ext4
  • Mainline Linux: GPL license, in kernel

vs ZFS:

  • Btrfs is mainline (no DKMS)
  • Btrfs handles mixed-size disks better
  • ZFS is more mature for RAID-Z and perf
  • ZFS has richer tooling ecosystem

Prerequisites

  • Linux VPS / server Debian 12 / Ubuntu / openSUSE / Fedora
  • Root access
  • Available disks

Step 1: Install tools

Kernel module already included. For tools:

sudo apt update
sudo apt install -y btrfs-progs
btrfs --version

Step 2: Simple filesystem

sudo mkfs.btrfs /dev/sdb
sudo mkdir /mnt/data
sudo mount /dev/sdb /mnt/data

Persist in /etc/fstab:

UUID=xxx-yyy /mnt/data btrfs defaults,compress=zstd,space_cache=v2 0 0
sudo blkid /dev/sdb

Step 3: Multi-device (Btrfs RAID)

2-disk RAID1:

sudo mkfs.btrfs -m raid1 -d raid1 /dev/sdb /dev/sdc
sudo mount /dev/sdb /mnt/data

-m = metadata, -d = data.

4-disk RAID10:

sudo mkfs.btrfs -m raid10 -d raid10 /dev/sdb /dev/sdc /dev/sdd /dev/sde

RAID5/6 still considered experimental for data. Avoid in prod.

Step 4: Subvolumes

A subvolume = lightweight "sub-FS" you can snapshot independently:

cd /mnt/data
sudo btrfs subvolume create @home
sudo btrfs subvolume create @var
sudo btrfs subvolume create @backups

sudo btrfs subvolume list /mnt/data

Mount a subvolume:

sudo mount -o subvol=@home /dev/sdb /home

On openSUSE and similar: rootfs typically subvolume @, /home is @home.

Step 5: Snapshots

Snapshots are actually subvolumes linked to parent:

sudo btrfs subvolume snapshot /mnt/data/@home /mnt/data/@home-snap-2026-05-17

Read-only snapshot:

sudo btrfs subvolume snapshot -r /mnt/data/@home /mnt/data/@home-readonly

List:

sudo btrfs subvolume list /mnt/data

Delete:

sudo btrfs subvolume delete /mnt/data/@home-snap-2026-05-17

Step 6: Compression

sudo mount -o remount,compress=zstd:3 /mnt/data

Or in fstab:

UUID=xxx /mnt/data btrfs defaults,compress=zstd:3 0 0

zstd levels: 1 (fast, less compression) to 15 (slow, more). 3 is the default sweet spot.

Force compression on existing files:

sudo btrfs filesystem defragment -r -czstd /mnt/data

See compression ratio:

sudo compsize /mnt/data

Install compsize if missing:

sudo apt install -y compsize

Step 7: Quotas

sudo btrfs quota enable /mnt/data
sudo btrfs qgroup show -reF /mnt/data
sudo btrfs qgroup limit 50G /mnt/data/@home

⚠️ Btrfs quotas have non-trivial perf cost on large FS. Enable sparingly.

Step 8: Send / Receive (incremental backup)

Like ZFS, Btrfs can send a snapshot to another Btrfs FS.

Read-only snapshot required:

sudo btrfs subvolume snapshot -r /mnt/data/@home /mnt/data/@home-2026-05-17

Send:

sudo btrfs send /mnt/data/@home-2026-05-17 | ssh root@backup "btrfs receive /mnt/backup/"

Incremental:

sudo btrfs send -p /mnt/data/@home-2026-05-16 /mnt/data/@home-2026-05-17 | ssh root@backup "btrfs receive /mnt/backup/"

Step 9: Scrub and balance

Scrub: integrity check (checksums):

sudo btrfs scrub start /mnt/data
sudo btrfs scrub status /mnt/data

Monthly cron:

0 2 1 * * /usr/bin/btrfs scrub start -B /mnt/data

Balance: redistributes block groups, useful after adding/removing disks:

sudo btrfs balance start -dconvert=raid1 /mnt/data
sudo btrfs balance status /mnt/data

Step 10: Add / remove a disk

Add:

sudo btrfs device add /dev/sdd /mnt/data
sudo btrfs balance start /mnt/data

Remove (content migrated elsewhere):

sudo btrfs device remove /dev/sdb /mnt/data

Replace dead disk:

sudo btrfs replace start /dev/sdb /dev/sde /mnt/data
sudo btrfs replace status /mnt/data

Step 11: Snapper (snapshot automation)

Snapper automates Btrfs snapshots with timeline and rollback:

sudo apt install -y snapper

sudo snapper -c root create-config /
sudo snapper -c home create-config /home

See config:

sudo snapper -c root list
sudo snapper -c root status 1..2     # diff between snapshots 1 and 2

Rollback:

sudo snapper -c root rollback 5

On openSUSE, snapper integrates with GRUB to boot any snapshot.

Step 12: ext4 -> btrfs conversion

Btrfs can convert existing ext4 in place:

sudo umount /dev/sdb
sudo btrfs-convert /dev/sdb
sudo mount /dev/sdb /mnt/data

Old ext4 stays as subvolume ext2_saved. Once verified:

sudo btrfs subvolume delete /mnt/data/ext2_saved

⚠️ Backup first. Conversion is risky on large FS.

Troubleshooting

"no space left on device" but df shows free

Btrfs manages data and metadata separately. Often metadata full:

sudo btrfs filesystem df /mnt/data
sudo btrfs balance start -dusage=50 /mnt/data

Degraded performance (fragmentation)

On DB, VMs, heavy I/O files, CoW fragments. Solutions:

sudo chattr +C /var/lib/mysql              # disable CoW for this dir
sudo btrfs filesystem defragment -r /var/lib/mysql

Mount fails after crash

sudo btrfs check /dev/sdb
sudo btrfs rescue super-recover /dev/sdb

⚠️ Don't use btrfs check --repair without backup, it's risky.

Scrub finds errors

Btrfs auto-repairs if RAID1+. Otherwise identifies corrupted files:

sudo btrfs scrub status -d /mnt/data
sudo dmesg | grep btrfs

Too many snapshots = slowness

Btrfs snapshots are cheap, but 10,000+ slows down. Snapper has retention policies:

sudo snapper -c root cleanup number

Useful commands

sudo mkfs.btrfs /dev/sdb
sudo btrfs filesystem show
sudo btrfs filesystem df /mnt/data
sudo btrfs filesystem usage /mnt/data

sudo btrfs subvolume list /mnt/data
sudo btrfs subvolume create / delete / snapshot

sudo btrfs device add / remove / replace
sudo btrfs device stats /mnt/data

sudo btrfs scrub start / status
sudo btrfs balance start / status
sudo btrfs filesystem defragment -r -czstd /mnt/data

sudo btrfs send / receive

sudo snapper -c root list
sudo snapper -c root create --description "before update"
sudo snapper -c root rollback 5

sudo btrfs check /dev/sdb
sudo dmesg | grep btrfs

Conclusion

Btrfs gives you:

  • Snapshots/CoW in mainline kernel (no DKMS)
  • Native compression and integrity
  • Online conversion, resize, defrag
  • Snapper integration for rollbacks

Limits:

  • Experimental RAID5/6 (avoid for critical data)
  • Quotas with overhead
  • Mixed historical reputation (RAID5 issues), but stable in RAID1 / single / 10 configs

Going further:

  • For servers with OS rollback, check openSUSE Tumbleweed or Garuda (btrfs + snapper integrated)
  • Combine with borg or restic for offsite backups
  • For VMs, disable CoW on images (chattr +C)

Resources

Join our Discord community server

For any questions, suggestions, or just to chat with the community, join us on Discord!

900+Members