--- title: "ext4 vs XFS vs Btrfs: Which Linux Filesystem to Choose" description: "Compare ext4, XFS and Btrfs on Linux: features, limits, resizing, snapshots and workloads, with hands-on loop device examples to help you pick the right one." category: "Storage Management" language: en source: https://cubepath.com/docs/storage-management/file-systems-ext4-xfs-btrfs-which-to-choose updated: 2026-09-25 --- # ext4 vs XFS vs Btrfs: Which Linux Filesystem to Choose ext4, XFS and Btrfs are the three general-purpose filesystems you will meet on Linux servers. ext4 is the default on Ubuntu and Debian, XFS on Red Hat Enterprise Linux and its rebuilds, and Btrfs on Fedora Workstation and openSUSE. This guide compares them feature by feature, lets you try each one safely on loop devices in Ubuntu 24.04, and ends with clear recommendations for common server workloads. ## Prerequisites To run the examples you need: - A server running Ubuntu 24.04 LTS, for example a CubePath VPS, with a non-root user that has `sudo` privileges. - About 12 GB of free disk space for three test images. The examples use loop devices (files that behave like disks), so no real disk is touched. Install the user-space tools for XFS and Btrfs. The ext4 tools (`e2fsprogs`) are already installed: ```bash sudo apt update sudo apt install xfsprogs btrfs-progs ``` ## Comparison at a glance | Feature | ext4 | XFS | Btrfs | |---------|------|-----|-------| | Default on | Ubuntu, Debian | RHEL, Rocky, AlmaLinux | Fedora Workstation, openSUSE | | Grow online | Yes | Yes | Yes | | Shrink | Yes, unmounted only | No | Yes, online | | Metadata checksums | Yes | Yes | Yes | | Data checksums | No | No | Yes | | Native snapshots | No (use LVM) | No (use LVM) | Yes | | Transparent compression | No | No | Yes (zstd, lzo, zlib) | | Built-in multi-disk / RAID | No | No | Yes (RAID 1 and 10 are stable; avoid RAID 5/6) | | Reflink copies (`cp --reflink`) | No | Yes | Yes | | Repair tool | `e2fsck` | `xfs_repair` | `btrfs check` (use with care) | | Maturity | Very high | Very high | High, some features still maturing | In short: ext4 is the simple, predictable choice; XFS scales best for large files and parallel I/O but cannot shrink; Btrfs adds snapshots, checksums for data and compression at the cost of more complexity. ## Setting up test devices Create three 4 GB image files and attach each one to a loop device. `losetup --show` prints the device it chose: ```bash sudo truncate -s 4G /var/tmp/ext4.img /var/tmp/xfs.img /var/tmp/btrfs.img sudo losetup --find --show /var/tmp/ext4.img sudo losetup --find --show /var/tmp/xfs.img sudo losetup --find --show /var/tmp/btrfs.img ``` ```output /dev/loop3 /dev/loop4 /dev/loop5 ``` Your numbers may differ, because snap packages already use some loop devices. The next sections use `/dev/loop3`, `/dev/loop4` and `/dev/loop5`; replace them with the ones printed on your system. ## ext4: the reliable default ext4 descends from ext2 and ext3 and has been the default Linux filesystem for more than a decade. It journals metadata, has fast `fsck` times, and every rescue tool and distribution knows it. Its limits (1 EiB per filesystem, 16 TiB per file with 4 KiB blocks) are far beyond what a single server needs. Create and mount an ext4 filesystem: ```bash sudo mkfs.ext4 -L test-ext4 /dev/loop3 sudo mkdir -p /mnt/ext4 sudo mount /dev/loop3 /mnt/ext4 ``` By default ext4 reserves 5% of the blocks for `root`, so that system services can still write when users fill the disk. On a large data disk that is a lot of wasted space. Check and lower it to 1%: ```bash sudo tune2fs -l /dev/loop3 | grep 'Reserved block count' sudo tune2fs -m 1 /dev/loop3 ``` ```output Reserved block count: 52428 tune2fs 1.47.0 (5-Feb-2023) Setting reserved blocks percentage to 1% (10485 blocks) ``` ext4 can also shrink, but only while unmounted and after a filesystem check. This shrinks the filesystem to 3 GB (the underlying device keeps its size): ```bash sudo umount /mnt/ext4 sudo e2fsck -f /dev/loop3 sudo resize2fs /dev/loop3 3G ``` ```output Resizing the filesystem on /dev/loop3 to 786432 (4k) blocks. The filesystem on /dev/loop3 is now 786432 (4k) blocks long. ``` **Choose ext4 when:** you want the default that works everywhere, the root filesystem of a VPS, general web and application servers, small to medium databases, or any disk you might need to shrink later. ## XFS: built for large files and parallel I/O XFS was designed by SGI for large storage systems. It splits the filesystem into allocation groups that can be written in parallel, which makes it very good with large files, many concurrent writers and big arrays. Red Hat uses it as the default for that reason. Create and mount an XFS filesystem: ```bash sudo mkfs.xfs -L test-xfs /dev/loop4 sudo mkdir -p /mnt/xfs sudo mount /dev/loop4 /mnt/xfs ``` Inspect its geometry. `agcount` is the number of allocation groups and `reflink=1` means copy-on-write file clones are enabled: ```bash sudo xfs_info /mnt/xfs ``` ```output meta-data=/dev/loop4 isize=512 agcount=4, agsize=262144 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=1, sparse=1, rmapbt=1 = reflink=1 bigtime=1 inobtcount=1 nrext64=0 data = bsize=4096 blocks=1048576, imaxpct=25 ``` XFS grows online, and it is always grown by mount point. Enlarge the image to 6 GB, tell the loop device about the new size, then grow the filesystem: ```bash sudo truncate -s 6G /var/tmp/xfs.img sudo losetup -c /dev/loop4 sudo xfs_growfs /mnt/xfs df -h /mnt/xfs ``` ```output Filesystem Size Used Avail Use% Mounted on /dev/loop4 6.0G 150M 5.8G 3% /mnt/xfs ``` The important limit: **XFS cannot be shrunk**. The only way to make an XFS filesystem smaller is to back it up, recreate it and restore the data, so do not give an XFS volume more space than you are sure it will keep. **Choose XFS when:** you store large files (media, backups, logs, object storage), run high-throughput databases on dedicated volumes, have large multi-disk arrays, or run RHEL-family systems where it is the tested default. ## Btrfs: snapshots, checksums and compression Btrfs is a copy-on-write filesystem: it never overwrites data in place, which makes cheap snapshots possible. It checksums both data and metadata, so it detects silent corruption, and it can compress data transparently. Create and mount a Btrfs filesystem with zstd compression: ```bash sudo mkfs.btrfs -L test-btrfs /dev/loop5 sudo mkdir -p /mnt/btrfs sudo mount -o compress=zstd /dev/loop5 /mnt/btrfs ``` Btrfs organizes data in subvolumes, which behave like independent directory trees that can be snapshotted and mounted separately. Create one and put a file in it: ```bash sudo btrfs subvolume create /mnt/btrfs/@data echo "version 1" | sudo tee /mnt/btrfs/@data/config.txt ``` Take a read-only snapshot. It is instant and uses no extra space until the data changes: ```bash sudo btrfs subvolume snapshot -r /mnt/btrfs/@data /mnt/btrfs/@data-snap1 echo "version 2" | sudo tee /mnt/btrfs/@data/config.txt cat /mnt/btrfs/@data-snap1/config.txt ``` ```output version 1 ``` The snapshot still holds the old content. List the subvolumes: ```bash sudo btrfs subvolume list /mnt/btrfs ``` ```output ID 256 gen 8 top level 5 path @data ID 257 gen 9 top level 5 path @data-snap1 ``` Because Btrfs allocates space in chunks for data and metadata separately, `df` can be misleading. Use Btrfs's own report: ```bash sudo btrfs filesystem usage /mnt/btrfs ``` Run a scrub to read every block and verify it against its checksum. On a multi-disk Btrfs with RAID 1, scrub also repairs bad copies from the good one: ```bash sudo btrfs scrub start -B /mnt/btrfs ``` ```output Scrub started: Thu Sep 24 10:20:11 2026 Status: finished Duration: 0:00:00 Total to scrub: 320.00KiB Error summary: no errors found ``` Keep these limitations in mind: - Copy-on-write fragments files that are rewritten in place, such as database files and VM disk images. For those, create the directory empty and disable CoW on it with `sudo chattr +C /path/to/dir`; files created inside then skip CoW, which also disables their checksums and compression. - The built-in RAID 5 and RAID 6 modes are still not recommended for production. Use RAID 1 or RAID 10, or put Btrfs on top of `mdadm`. - When the metadata space fills up, writes can fail with `No space left on device` even though `df` shows free space. A filtered balance usually frees it: `sudo btrfs balance start -dusage=50 /mnt/btrfs`. **Choose Btrfs when:** you want snapshots before upgrades or for backups (`btrfs send` and `receive`), you store compressible data such as logs, text or source code, you want data checksums on a workstation or small file server, or you run openSUSE or Fedora where it is well integrated. ## Which one should you choose For most cases the decision is short: | Workload | Recommendation | |----------|----------------| | Root filesystem of a VPS or general server | ext4, the Ubuntu and Debian default | | MySQL, PostgreSQL on a dedicated volume | ext4 or XFS | | Large files, backups, media, log archives | XFS | | Big multi-disk arrays with high parallel I/O | XFS on `mdadm` or LVM | | Frequent snapshots, rollback before upgrades | Btrfs, or ext4/XFS on LVM with snapshots | | Compressible data, space-constrained disks | Btrfs with `compress=zstd` | | Disks you may need to shrink later | ext4 or Btrfs, not XFS | If you are unsure, use ext4. It is the most forgiving choice, and the tools to repair and resize it are always available. Pick XFS for scale and Btrfs for its features, not by default. You can check which filesystem any mount uses with: ```bash findmnt -no FSTYPE / ``` ```output ext4 ``` ## Cleaning up the test devices Unmount the filesystems, detach the loop devices and remove the images: ```bash sudo umount /mnt/ext4 /mnt/xfs /mnt/btrfs sudo losetup -d /dev/loop3 /dev/loop4 /dev/loop5 sudo rm /var/tmp/ext4.img /var/tmp/xfs.img /var/tmp/btrfs.img ``` `/mnt/ext4` was already unmounted during the shrink test, so `umount` may report that it is not mounted; that is expected. ## Conclusion ext4 is the safe default, XFS scales best for large files and parallel workloads but cannot shrink, and Btrfs adds snapshots, data checksums and compression in exchange for more care around databases and multi-disk setups. As next steps, partition and format a real data disk with the filesystem you picked, add LVM underneath ext4 or XFS if you want flexible resizing and snapshots, and schedule regular checks: `fstrim.timer` for SSDs is already enabled on Ubuntu, and a monthly `btrfs scrub` is worthwhile on Btrfs.