BTRFS (B-tree File System) is a modern copy-on-write filesystem for Linux with integrated volume management, snapshots, checksumming, and multi-device support.

Table of Contents#

  1. Overview
  2. Filesystem Management
  3. Subvolumes
  4. Snapshots
  5. Device Management
  6. RAID Configuration
  7. Scrub and Data Integrity
  8. Compression
  9. Quota Groups (qgroups)
  10. Mount Options
  11. Special Use Cases
  12. Troubleshooting
  13. See Also
  14. Sources

1. Overview#

BTRFS is a copy-on-write (CoW) filesystem that integrates volume management features directly into the filesystem layer. It was designed to address the scaling and reliability needs of modern Linux storage.

Key features:

  • Copy-on-Write (CoW) - data is never overwritten in place; new data is written to a new location, then metadata is atomically updated
  • Built-in checksumming - CRC32C (default), xxhash, sha256, or blake2b for both data and metadata
  • Snapshots - instant, space-efficient snapshots via CoW
  • Subvolumes - lightweight logical divisions within a filesystem
  • Integrated multi-device - RAID 0, 1, 10, 5 (unstable), 6 (unstable), and single profiles
  • Online resize - grow and shrink while mounted
  • Transparent compression - zstd, lzo, or zlib
  • Send/receive - incremental replication between BTRFS filesystems

Kernel Version Dependencies#

Several BTRFS features depend on the kernel version:

FeatureMinimum KernelNotes
discard=async6.2Enabled by default since 6.2
space_cache=v24.5Default since 4.12
RAID 5/63.19Still considered unstable; not recommended for production
zstd compression4.14Recommended compression algorithm
Send/receive v26.0Supports large files, encoded inline extents
Block group tree6.1Faster mount times for large filesystems

2. Filesystem Management#

Creating a Filesystem#

# Single device
mkfs.btrfs -L <label> /dev/<device>

# Multiple devices (RAID 1 for data, RAID 1 for metadata)
mkfs.btrfs -L <label> -d raid1 -m raid1 /dev/sda /dev/sdb

Mounting#

mount /dev/<device> /mnt

# With specific subvolume
mount -o subvol=@ /dev/<device> /mnt

Resizing#

# Grow to fill available space
btrfs filesystem resize max /mnt

# Grow by a specific amount
btrfs filesystem resize +10G /mnt

# Shrink by a specific amount
btrfs filesystem resize -5G /mnt

# Shrink to a specific size
btrfs filesystem resize 50G /mnt

Checking Usage#

# Detailed usage breakdown (data, metadata, system)
btrfs filesystem usage /mnt

# Per-device usage
btrfs filesystem show /mnt

# Disk free with allocation detail
btrfs filesystem df /mnt

Properties#

# Set compression on a directory
btrfs property set /path compression zstd

# Make a subvolume read-only
btrfs property set /path ro true

# Disable CoW for a directory (must be set before files are created)
chattr +C /path/to/directory

3. Subvolumes#

Subvolumes are independent POSIX filesystem trees within a BTRFS filesystem. They share the same pool of storage but can be independently snapshotted, mounted, and configured.

Creating Subvolumes#

# Create subvolumes
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@log
btrfs subvolume create /mnt/@snapshots

Listing Subvolumes#

btrfs subvolume list /mnt
btrfs subvolume list -t /mnt   # table format with gen, top level

Mounting Specific Subvolumes#

# Via fstab
/dev/sda  /         btrfs  subvol=@,compress=zstd,noatime       0 0
/dev/sda  /home     btrfs  subvol=@home,compress=zstd,noatime   0 0
/dev/sda  /var/log  btrfs  subvol=@log,compress=zstd,noatime    0 0

Deleting Subvolumes#

btrfs subvolume delete /mnt/@old

Default Subvolume#

# Set the default subvolume (mounted when no subvol= option is given)
btrfs subvolume set-default <subvol-id> /mnt

4. Snapshots#

Snapshots are instant copies of subvolumes. They are created in constant time regardless of the amount of data, thanks to CoW.

Creating Snapshots#

# Writable snapshot
btrfs subvolume snapshot /mnt/@ /mnt/@snapshots/@-$(date +%Y%m%d)

# Read-only snapshot (required for send/receive)
btrfs subvolume snapshot -r /mnt/@ /mnt/@snapshots/@-$(date +%Y%m%d)

Restoring from a Snapshot#

# Rename the current subvolume
mv /mnt/@ /mnt/@broken

# Create a writable snapshot from the backup
btrfs subvolume snapshot /mnt/@snapshots/@-20260301 /mnt/@

# Reboot or remount

Send/Receive (Incremental Replication)#

# Full send of a read-only snapshot
btrfs send /mnt/@snapshots/@-20260301 | btrfs receive /backup/

# Incremental send (only changes since the parent snapshot)
btrfs send -p /mnt/@snapshots/@-20260301 /mnt/@snapshots/@-20260302 | \
  btrfs receive /backup/

Deleting Old Snapshots#

btrfs subvolume delete /mnt/@snapshots/@-20260201

5. Device Management#

BTRFS can span multiple devices and supports online addition, removal, and replacement of devices.

Adding a Device#

# Add a new device to the filesystem
btrfs device add /dev/sdc /mnt

# Rebalance data across all devices
btrfs balance start /mnt

Removing a Device#

# Remove a device (data is migrated to remaining devices)
btrfs device remove /dev/sdb /mnt

Replacing a Failed Device#

# Online replacement (data is copied from remaining redundant copies)
btrfs replace start <devid> /dev/new_device /mnt

# Monitor replacement progress
btrfs replace status /mnt

Get the device ID with:

btrfs filesystem show /mnt

Mounting a Degraded Filesystem#

If a device is missing (failed or disconnected), mount in degraded mode:

mount -o degraded /dev/sda /mnt

Then replace the missing device as soon as possible.

6. RAID Configuration#

Metadata Redundancy#

By default, BTRFS stores metadata in DUP mode on single devices (two copies on the same device) and RAID1 on multi-device setups. This provides metadata protection even in non-RAID configurations.

ProfileCopiesMin DevicesNotes
single11No redundancy
dup21Default for metadata on single device
raid012Striped, no redundancy
raid122Mirrored on 2 devices
raid1c333Mirrored on 3 devices
raid1c444Mirrored on 4 devices
raid1024Striped mirrors
raid51+parity3Unstable, not recommended
raid61+2parity4Unstable, not recommended

Converting Between RAID Profiles#

# Convert data to RAID 1
btrfs balance start -dconvert=raid1 /mnt

# Convert metadata to RAID 1
btrfs balance start -mconvert=raid1 /mnt

# Convert both simultaneously
btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt

# Run in background
btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt --background

# Check balance status
btrfs balance status /mnt

Verifying RAID Profile#

btrfs filesystem usage /mnt

Look for the "Data" and "Metadata" profile lines in the output.

7. Scrub and Data Integrity#

Scrub reads all data and metadata from disk, verifies checksums, and repairs any corruption found using redundant copies (if available).

Running a Scrub#

# Start a scrub
btrfs scrub start /mnt

# Start a scrub in the foreground (wait for completion)
btrfs scrub start -B /mnt

# Check scrub status
btrfs scrub status /mnt

Scheduling Regular Scrubs#

Create a systemd timer for regular scrubbing:

# /etc/systemd/system/btrfs-scrub@.timer
[Unit]
Description=Monthly BTRFS scrub on %i

[Timer]
OnCalendar=monthly
Persistent=true
RandomizedDelaySec=1w

[Install]
WantedBy=timers.target
# /etc/systemd/system/btrfs-scrub@.service
[Unit]
Description=BTRFS scrub on %i

[Service]
Type=oneshot
ExecStart=/usr/bin/btrfs scrub start -B %i
IOSchedulingClass=idle
CPUSchedulingPolicy=idle
sudo systemctl enable --now btrfs-scrub@mnt.timer

Many distributions (e.g., openSUSE, Fedora) ship with btrfs-scrub@.timer preinstalled.

Scrub Results#

btrfs scrub status /mnt

Key output fields:

FieldMeaning
data_extents_scrubbedNumber of data extents verified
csum_errorsChecksum mismatches found
verify_errorsMetadata verification failures
corrected_errorsErrors corrected from redundant copies
uncorrectable_errorsErrors that could not be repaired (data loss)

8. Compression#

BTRFS supports transparent, per-file compression.

AlgorithmRatioCPU UsageBest For
zstdBestModerateGeneral purpose (recommended)
lzoLowLowestReal-time workloads
zlibGoodHighestMaximum compression ratio

Enabling Compression#

# At mount time
mount -o compress=zstd /dev/sda /mnt

# Per-directory
btrfs property set /mnt/data compression zstd

# Compress existing files (defragment with compression)
btrfs filesystem defragment -r -czstd /mnt/data

Compression Levels#

# zstd supports levels 1-15 (default 3)
mount -o compress=zstd:3 /dev/sda /mnt

9. Quota Groups (qgroups)#

Quota groups track and limit space usage per subvolume. They are organized in a hierarchy.

Hierarchy#

Level 0: Individual subvolumes (automatically created)
  0/256 = subvolume @ (root)
  0/257 = subvolume @home
  0/258 = subvolume @log

Level 1+: User-defined group limits
  1/0   = group containing 0/256, 0/257, 0/258

Each qgroup at level 0 tracks the exclusive and shared space of its subvolume. Higher-level qgroups aggregate the limits of their children.

Enabling and Using Quotas#

# Enable quotas (may cause minor performance overhead)
btrfs quota enable /mnt

# Show quota usage
btrfs qgroup show -reF /mnt

# Set a limit on a subvolume
btrfs qgroup limit 50G /mnt/@home

# Set a limit on a higher-level group
btrfs qgroup create 1/0 /mnt
btrfs qgroup assign 0/257 1/0 /mnt
btrfs qgroup limit 100G 1/0 /mnt

# Remove a limit
btrfs qgroup limit none /mnt/@home

# Disable quotas
btrfs quota disable /mnt

Performance Note#

Enabling quotas adds bookkeeping overhead to every write operation. On workloads with many small writes or frequent snapshot creation, this overhead can be noticeable. Consider enabling quotas only when space enforcement is required.

10. Mount Options#

OptionDescriptionDefault
compress=zstdTransparent compression (zstd recommended)Disabled
compress=lzoTransparent compression with LZODisabled
compress=zlibTransparent compression with zlibDisabled
nocompressDisable compressionN/A
discard=asyncAsynchronous TRIM for SSDsEnabled (kernel 6.2+)
discard=syncSynchronous TRIM for SSDsDisabled
nodiscardDisable TRIMDisabled
noatimeDo not update access timesDisabled (recommended to enable)
autodefragAutomatic defragmentationDisabled
space_cache=v2Free space cache version 2Enabled (kernel 4.12+)
ssdSSD optimizationsAuto-detected
nodatacowDisable CoW for data (not recommended)Disabled
nospace_cacheDisable free space cache (degrades performance)Disabled
commit=<sec>Commit interval in seconds30
degradedMount with missing devicesDisabled
subvol=<path>Mount a specific subvolume by pathTop-level
subvolid=<id>Mount a specific subvolume by IDTop-level
roRead-only mountDisabled
noaclDisable ACLsDisabled

Source: btrfs man page

/dev/sda  /  btrfs  subvol=@,compress=zstd,noatime,space_cache=v2  0 0

Important Notes#

  • nodatacow: Disables CoW, checksumming, and compression for affected files. Only use for specific workloads (databases, VM images).
  • autodefrag: Helpful for random-write workloads on HDDs; may increase I/O on SSDs.
  • noatime: Recommended for all workloads; reduces unnecessary writes.

11. Special Use Cases#

Database Performance Optimization#

Databases perform many small random writes, which conflict with BTRFS CoW behavior. Disable CoW for database data directories:

# Create a subvolume for the database
btrfs subvolume create /mnt/@database

# Set the no-CoW attribute (must be done before files are created)
chattr +C /mnt/@database

This disables CoW, checksumming, and compression for files in the directory.

Swap File on BTRFS#

BTRFS supports swap files starting with kernel 5.0, with restrictions:

# Create swap file (must be no-CoW, no compression, single extent)
btrfs filesystem mkswapfile --size 4G /mnt/swapfile

# Or manually (kernel < 6.1)
truncate -s 0 /mnt/swapfile
chattr +C /mnt/swapfile
fallocate -l 4G /mnt/swapfile
chmod 600 /mnt/swapfile
mkswap /mnt/swapfile
swapon /mnt/swapfile

VM Images#

For virtual machine disk images, disable CoW to avoid fragmentation and write amplification:

mkdir /mnt/@vms
chattr +C /mnt/@vms

Troubleshooting#

IssueCauseSolution
No space left on device but df shows free spaceMetadata space exhausted or unbalanced allocationRun btrfs filesystem usage /mnt; if metadata is full, rebalance: btrfs balance start -musage=50 /mnt
Extremely slow deletes or snapshot removalqgroups accounting overheadDisable quotas if not needed: btrfs quota disable /mnt
BTRFS warning: csum failed in dmesgData corruption detected by checksumsRun btrfs scrub start /mnt; if redundant copies exist, scrub will auto-repair
Mount fails after unclean shutdownLog tree corruptionTry btrfs rescue zero-log /dev/sda; if that fails, try btrfs check --repair /dev/sda (last resort)
Degraded mount requiredDevice missing or failedMount with -o degraded; replace the device immediately
Balance never completesNot enough free space to relocate block groupsFree space by deleting old snapshots or data; use filter flags: btrfs balance start -dusage=10 /mnt
RAID 5/6 data lossKnown write-hole bug in BTRFS RAID 5/6Do not use BTRFS RAID 5/6 for production; migrate to RAID 1 or use mdadm/ZFS for RAID 5/6
High fragmentation on HDDCoW behavior creates fragmentation over timeEnable autodefrag mount option; periodically run btrfs filesystem defragment -r /mnt

See Also#

Sources#