$linuxjunkies
>

ZFS vs Btrfs on Linux

ZFS vs Btrfs on Linux: a direct comparison of maturity, licensing, RAID safety, snapshots, performance, and which filesystem to pick for your use case.

IntermediateUbuntuDebianFedoraArch9 min readUpdated June 7, 2026

Before you start

  • Root or sudo access on the target system
  • Basic familiarity with Linux filesystems and partitioning concepts
  • For ZFS: a kernel with DKMS support and build headers installed
  • For multi-disk setups: unformatted block devices or a test VM with extra disks

ZFS and Btrfs are both copy-on-write (COW) filesystems that promise data integrity, snapshots, and built-in RAID — but they come from different worlds, carry different trade-offs, and suit different workloads. Choosing between them without understanding those differences leads to surprises in production. This guide cuts through the noise with a direct feature comparison, licensing context, and a practical decision framework.

Background and Lineage

ZFS was created at Sun Microsystems, released as open source in 2005 under the CDDL license. After Oracle acquired Sun, the community forked it as OpenZFS, which now ships on Linux, FreeBSD, macOS, and illumos. OpenZFS 2.x is the version you use today.

Btrfs (B-tree filesystem) was started at Oracle in 2007 and merged into the mainline Linux kernel in 2009. It is licensed under the GPL and developed in-tree. Red Hat, SUSE, and Facebook (Meta) have all contributed heavily at different points.

Kernel Licensing: Why It Matters Practically

ZFS (CDDL) and the Linux kernel (GPL v2) are incompatible licenses. OpenZFS cannot be merged into the mainline kernel. On every distro, ZFS is delivered as an out-of-tree kernel module, either compiled from source via DKMS or shipped as pre-built binaries.

Btrfs is GPL, lives in-tree, ships with every standard kernel, and needs no extra packages. For environments where touching out-of-tree modules is forbidden — some enterprise security policies, certain cloud VM images, locked-down UEFI Secure Boot setups — Btrfs is the only choice.

Installing ZFS on Debian/Ubuntu (via the official ZFS-on-Linux packages):

sudo apt install zfsutils-linux zfs-dkms

On Fedora 39+ or RHEL 9 clones (requires the OpenZFS repository):

sudo dnf install https://zfsonlinux.org/fedora/zfs-release-2-5$(rpm --eval "%{dist}").noarch.rpm
sudo dnf install zfs

On Arch Linux:

sudo pacman -S zfs-dkms zfs-utils

Btrfs tools are already present on most distros; you only need the userspace utilities:

# Debian/Ubuntu
sudo apt install btrfs-progs

# Fedora/RHEL
sudo dnf install btrfs-progs

# Arch
sudo pacman -S btrfs-progs

Maturity and Stability

ZFS has over two decades of production use on Solaris and FreeBSD before it ever ran on Linux. Its RAID-Z implementation, checksumming engine, and ARC (Adaptive Replacement Cache) are battle-tested at extreme scale. Enterprise storage appliances from NetApp competitors, TrueNAS, and countless hyperscalers run OpenZFS.

Btrfs has a more uneven history. Its basic features — subvolumes, snapshots, compression, and single-device use — are stable and widely deployed. SUSE Linux Enterprise has shipped Btrfs as the default root filesystem since SLE 12. However, Btrfs RAID 5 and RAID 6 have carried known data-loss bugs for years and are still not recommended for production data as of kernel 6.x. For multi-disk redundancy with Btrfs, use RAID 1 or RAID 10 only.

Feature Comparison

FeatureZFS (OpenZFS 2.x)Btrfs (kernel 6.x)
SnapshotsInstantaneous, space-efficientInstantaneous, space-efficient
Send/receive replicationYes, mature (zfs send)Yes (btrfs send), fewer options
Transparent compressionLZ4, GZIP, ZSTD, LZOZLIB, LZO, ZSTD
Inline deduplicationYes (RAM-heavy; use carefully)No (out-of-band only with external tools)
RAIDRAID-Z1/Z2/Z3, mirror, dRAIDRAID 1, RAID 10 (safe); RAID 5/6 (unsafe)
EncryptionNative dataset encryption (OpenZFS 2.0+)No native encryption; use dm-crypt underneath
QuotasPer-dataset, per-projectPer-subvolume, per-qgroup
ChecksummingEnd-to-end, all metadata and dataMetadata always; data checksums on by default
Pool/volume managementIntegrated (zpools)Relies on kernel device stack or LVM
Kernel integrationOut-of-tree DKMS moduleIn-tree, upstream kernel

Performance Characteristics

ZFS performance is dominated by RAM. The ARC caches filesystem data aggressively and defaults to using up to half of system RAM. On a server with 64 GB RAM, ZFS can be extraordinarily fast for read-heavy workloads. Add an SSD as an L2ARC read cache or a dedicated SLOG device for synchronous write acceleration. RAM-constrained systems (under 8 GB) should approach ZFS cautiously — the general recommendation is 1 GB RAM per 1 TB of storage, though modern OpenZFS is less demanding than the old 1 GB/TB rule suggested.

Btrfs has lower baseline overhead. It performs well on desktop hardware with limited RAM, and its ZSTD compression often yields better real-world throughput than raw uncompressed I/O when CPU is not the bottleneck. On NVMe-heavy systems with many small random writes, Btrfs COW can cause fragmentation over time; periodic btrfs balance and btrfs defragment operations mitigate this.

Snapshots and Replication in Practice

ZFS Snapshots

# Create a recursive snapshot of a dataset
sudo zfs snapshot -r tank/data@2025-01-15

# List snapshots
sudo zfs list -t snapshot

# Send an incremental stream to a remote host
sudo zfs send -i tank/data@2025-01-14 tank/data@2025-01-15 \
  | ssh backup-host sudo zfs receive backup/data

Btrfs Snapshots

# Create a read-only snapshot
sudo btrfs subvolume snapshot -r /data /data-snapshots/2025-01-15

# Send snapshot to a remote host
sudo btrfs send /data-snapshots/2025-01-15 \
  | ssh backup-host sudo btrfs receive /backup/data-snapshots/

ZFS send/receive tracks incremental differences through the pool's internal transaction log, making complex replication pipelines straightforward. Btrfs send works well for simple cases but lacks per-stream encryption and some filtering options that ZFS provides natively.

Enabling Compression

# ZFS: enable ZSTD compression on a dataset
sudo zfs set compression=zstd tank/data

# Verify
sudo zfs get compression,compressratio tank/data
# Btrfs: mount with ZSTD compression
sudo mount -o compress=zstd /dev/sdX /mnt/data

# Or set it persistently in /etc/fstab
# UUID=... /data btrfs compress=zstd 0 0

What to Choose

Use ZFS when:

  • You need proven multi-disk RAID with self-healing (NAS, file servers, backup targets).
  • You want native encryption + compression + dedup in one layer.
  • You have sufficient RAM (8 GB minimum; 16 GB+ recommended for pools over 4 TB).
  • You are building a TrueNAS, Proxmox, or similar appliance-style system.
  • You need mature, auditable send/receive replication pipelines.

Use Btrfs when:

  • You want snapshots and compression on a desktop or laptop with limited RAM.
  • You cannot use out-of-tree kernel modules (policy, Secure Boot, embedded systems).
  • Your distro defaults to it (SUSE/openSUSE, Fedora Workstation since F33) and you want full integration with tools like snapper.
  • You are running single-disk or simple two-disk mirror setups where Btrfs RAID 1 is safe.
  • You need a lightweight filesystem for containers or VMs where pool management overhead is undesirable.

Verification

# ZFS: confirm pool health and checksum error count
sudo zpool status -v tank
# Btrfs: run a scrub and check for errors
sudo btrfs scrub start /data
sudo btrfs scrub status /data

Both commands should report zero errors on healthy arrays. Schedule zpool scrub or btrfs scrub monthly via a systemd timer or cron job — silent data corruption only surfaces if you look for it.

Troubleshooting

ZFS module not loading after kernel update: DKMS should rebuild the module automatically, but if it fails, run sudo dkms autoinstall and check dmesg. On systems with Secure Boot and MOK enrollment, the new module may need re-signing.

Btrfs fragmentation and slowdowns: Heavy random-write workloads fragment COW files. Run sudo btrfs filesystem defragment -r -v -czstd /data during a maintenance window. For databases, consider placing the database files on a subvolume with nodatacow set.

ZFS pool imported read-only after unclean shutdown: This means the pool has an unfinished transaction. Run sudo zpool import -F tank to replay the log. Always confirm with zpool status before writing data.

Btrfs balance stuck or taking forever: Large balances on full or nearly-full volumes can stall. Ensure at least 10–15% free space before balancing, and use btrfs balance pause /data to safely pause and resume.

tested on:Ubuntu 24.04Fedora 40Arch 2025.01openSUSE Leap 15.6

Frequently asked questions

Is ZFS safe to use on Linux despite the license incompatibility?
Yes. The CDDL/GPL incompatibility prevents ZFS from being merged into the kernel, but it does not make using OpenZFS illegal. It ships as a loadable module and is used in production by major Linux distributions including Ubuntu (which includes it by default) and Proxmox.
Can Btrfs replace ZFS for a home NAS with multiple drives?
For two-disk mirrors, Btrfs RAID 1 is stable and works fine. For three or more drives where you need parity-based redundancy, stick with ZFS RAID-Z — Btrfs RAID 5/6 is not production-safe as of kernel 6.x.
Does ZFS really need 1 GB of RAM per 1 TB of storage?
That old rule comes from early ZFS on Solaris. Modern OpenZFS 2.x runs adequately with much less RAM; 8 GB is a reasonable minimum for a home server with several terabytes. Deduplication is the feature that truly explodes RAM requirements, not basic pool operation.
Which filesystem does Fedora Workstation use by default, and should I keep it?
Fedora Workstation has defaulted to Btrfs since Fedora 33. The default setup with subvolumes and automatic snapper integration works well for desktops. Unless you specifically need ZFS features, keeping the default is sensible.
Can I use both ZFS and Btrfs on the same system?
Yes. A common setup is ZFS for a multi-disk data pool and Btrfs (or ext4) for the root filesystem. They operate independently; just make sure the ZFS module loads before any ZFS pools are imported at boot, which the zfs-import systemd services handle automatically.

Related guides