Choosing a Filesystem

    Compare ext4, XFS, and Btrfs — and know when to use each one

    A filesystem determines how data is stored, organized, and retrieved on your disk. Choosing the right one affects performance, reliability, and the features available to you. On Linux, you have three main choices: ext4, XFS, and Btrfs. Each excels in different scenarios.

    What You'll Learn

    Key features and trade-offs of each filesystem
    Which filesystem to pick for your workload
    How to format, mount, and tune each one
    How to check and repair filesystem issues

    Prerequisites

    1. Quick Comparison

    Featureext4XFSBtrfs
    Max volume size1 EiB8 EiB16 EiB
    Max file size16 TiB8 EiB16 EiB
    Journaling✅ Full✅ Metadata only✅ Copy-on-write
    Online grow
    Online shrink❌ (offline only)
    Snapshots✅ Native
    Compression✅ (zstd, lzo, zlib)
    ChecksumsMetadata onlyMetadata only✅ Data + metadata
    Deduplication❌ (via reflink)✅ Offline
    Subvolumes
    Small-file perf⭐ ExcellentGoodGood
    Large-file perfGood⭐ ExcellentGood
    Parallel I/OGood⭐ ExcellentGood
    Maturity⭐ 2008, battle-tested⭐ 1993, proven2009, maturing
    Default onDebian, UbuntuRHEL, AlmaLinux, RockyFedora, openSUSE

    2. ext4 — The Reliable Default

    ext4 (Fourth Extended Filesystem) is the most widely used Linux filesystem. It evolved from ext3 and has been the default on Debian and Ubuntu for over 15 years. It's the safest, most predictable choice for general-purpose workloads.

    Strengths

    • Battle-tested reliability — used on billions of systems, extremely stable
    • Excellent small-file performance — great for web serving, mail, and mixed workloads
    • Low overhead — minimal CPU and RAM usage
    • Offline shrink support — the only one of the three that can be shrunk
    • Widest tooling support — every recovery and repair tool works with ext4

    Limitations

    • No built-in snapshots or compression
    • Doesn't checksum file data (only metadata)
    • Slower than XFS for very large sequential writes and highly parallel I/O

    💡 Best for: General-purpose VPS, web servers, WordPress/PHP, databases (MySQL/MariaDB/PostgreSQL), mail servers, and any workload where stability is the top priority.

    3. XFS — The Performance Powerhouse

    XFS was originally developed by SGI in 1993 for their IRIX workstations handling massive video and scientific data. It's designed from the ground up for high throughput, large files, and parallel I/O. RHEL, AlmaLinux, and Rocky Linux use it as their default.

    Strengths

    • Excellent large-file performance — streaming, video, backups, databases with large tablespaces
    • Best parallel I/O — scales linearly with CPU cores for concurrent operations
    • Delayed allocation — optimizes write placement, reducing fragmentation
    • Reflink copies — instant copy-on-write file clones (since Linux 4.9+)
    • Online defragmentationxfs_fsr while mounted

    Limitations

    • Cannot be shrunk — only grown. Plan your initial size carefully.
    • No built-in snapshots or compression
    • Slightly slower than ext4 for many small files and metadata-heavy operations

    💡 Best for: High-throughput workloads, large databases, media storage, backup servers, CI/CD build servers, and any scenario with large files or heavy concurrent I/O.

    4. Btrfs — The Feature-Rich Modern Option

    Btrfs (B-tree Filesystem, pronounced "butter-FS") is a copy-on-write filesystem that brings features like snapshots, compression, and checksumming that traditionally required separate tools or volume managers. It's the default on Fedora and openSUSE.

    Strengths

    • Native snapshots — instant, space-efficient snapshots for backups and rollbacks
    • Transparent compression — zstd, lzo, or zlib; saves disk space automatically
    • Data checksumming — detects silent data corruption (bit rot)
    • Subvolumes — logical divisions within a filesystem, each mountable independently
    • Online shrink and grow — resize in both directions while mounted
    • Send/receive — incrementally replicate snapshots between servers

    Limitations

    • RAID 5/6 is unstable — do not use Btrfs RAID 5/6 in production (RAID 1/10 are fine)
    • Higher overhead — copy-on-write and checksumming use more CPU and RAM
    • Fragmentation — copy-on-write can fragment heavily under random-write workloads (databases)
    • Space accounting — free space reporting can be confusing with snapshots and compression

    ⚠️ Database warning: Btrfs's copy-on-write causes significant fragmentation and performance degradation with databases (MySQL, PostgreSQL, MongoDB). If you must use Btrfs with databases, disable COW on the data directory: chattr +C /var/lib/mysql (must be set before data is written).

    💡 Best for: Development environments, NAS/file servers, systems needing snapshot-based backups, containers (Docker uses Btrfs snapshots), and workloads where data integrity verification matters.

    5. When to Use What

    WorkloadRecommendedWhy
    General web serverext4Stable, fast for mixed small/medium files, lowest overhead
    WordPress / PHPext4Handles many small files (themes, plugins, uploads) efficiently
    MySQL / MariaDB / PostgreSQLext4 or XFSBoth handle database I/O well; avoid Btrfs COW fragmentation
    Large database (100GB+)XFSSuperior large-file I/O and parallel write performance
    Media / video storageXFSBest sequential read/write for large files
    Backup serverXFS or BtrfsXFS for raw speed; Btrfs if you want compression + snapshots
    CI/CD build serverXFSExcellent parallel I/O for concurrent builds
    File server / NASBtrfsSnapshots, checksumming, and compression are valuable
    Docker hostext4 or XFSBoth work well with overlay2; XFS needs d_type=true
    Dev / testing environmentBtrfsSnapshots let you roll back instantly after experiments
    "I just want it to work"ext4Safest default — nothing to configure, nothing to surprise you

    💡 Rule of thumb: If you're unsure, use ext4. It's the safest default. If you know you'll be handling large files or need high-throughput I/O, choose XFS. If you need snapshots or compression built into the filesystem, choose Btrfs.

    6. Formatting & Mounting

    These examples use /dev/vdb as the target device — a common name for block storage volumes. Replace with your actual device.

    ⚠️ Warning: Formatting erases all data on the target device. Double-check the device name with lsblk before running mkfs.

    ext4

    Format and mount ext4
    # Format as ext4
    sudo mkfs.ext4 /dev/vdb
    
    # With a label
    sudo mkfs.ext4 -L mydata /dev/vdb
    
    # Mount
    sudo mkdir -p /mnt/data
    sudo mount /dev/vdb /mnt/data
    
    # Add to /etc/fstab for persistent mount
    echo '/dev/vdb /mnt/data ext4 defaults 0 2' | sudo tee -a /etc/fstab

    XFS

    Format and mount XFS
    # Format as XFS
    sudo mkfs.xfs /dev/vdb
    
    # With a label
    sudo mkfs.xfs -L mydata /dev/vdb
    
    # Mount
    sudo mkdir -p /mnt/data
    sudo mount /dev/vdb /mnt/data
    
    # Add to /etc/fstab
    echo '/dev/vdb /mnt/data xfs defaults 0 0' | sudo tee -a /etc/fstab

    Btrfs

    Format and mount Btrfs
    # Install Btrfs tools if needed
    sudo apt install btrfs-progs        # Debian/Ubuntu
    sudo dnf install btrfs-progs        # AlmaLinux/RHEL
    
    # Format as Btrfs
    sudo mkfs.btrfs /dev/vdb
    
    # With a label
    sudo mkfs.btrfs -L mydata /dev/vdb
    
    # Mount
    sudo mkdir -p /mnt/data
    sudo mount /dev/vdb /mnt/data
    
    # Mount with compression enabled
    sudo mount -o compress=zstd /dev/vdb /mnt/data
    
    # Add to /etc/fstab with compression
    echo '/dev/vdb /mnt/data btrfs defaults,compress=zstd 0 0' | sudo tee -a /etc/fstab

    Btrfs Subvolumes

    Create and use subvolumes
    # Create subvolumes
    sudo btrfs subvolume create /mnt/data/@home
    sudo btrfs subvolume create /mnt/data/@logs
    
    # Mount a specific subvolume
    sudo mount -o subvol=@home /dev/vdb /home
    sudo mount -o subvol=@logs /dev/vdb /var/log
    
    # List subvolumes
    sudo btrfs subvolume list /mnt/data
    
    # Create a snapshot
    sudo btrfs subvolume snapshot /mnt/data/@home /mnt/data/@home-snapshot
    
    # Create a read-only snapshot (for backups)
    sudo btrfs subvolume snapshot -r /mnt/data/@home /mnt/data/@home-backup
    Check which filesystem you're using
    # Show filesystem type for all mounts
    df -Th
    
    # Show filesystem type for a specific device
    lsblk -f

    7. Checking & Repairing

    ⚠️ Important: Filesystem checks for ext4 and XFS must be run on unmounted filesystems (or in read-only mode). Btrfs scrub can run online.

    ext4

    Check and repair ext4
    # Check (must be unmounted)
    sudo umount /dev/vdb
    sudo e2fsck -f /dev/vdb
    
    # Auto-fix errors
    sudo e2fsck -fy /dev/vdb
    
    # Check and report without fixing
    sudo e2fsck -n /dev/vdb

    XFS

    Check and repair XFS
    # Check (must be unmounted)
    sudo umount /dev/vdb
    sudo xfs_repair /dev/vdb
    
    # Dry run (check only)
    sudo xfs_repair -n /dev/vdb

    Btrfs

    Check and repair Btrfs
    # Online scrub (can run while mounted — checks data integrity)
    sudo btrfs scrub start /mnt/data
    
    # Check scrub status
    sudo btrfs scrub status /mnt/data
    
    # Offline check (must be unmounted)
    sudo umount /dev/vdb
    sudo btrfs check /dev/vdb
    
    # Show filesystem usage
    sudo btrfs filesystem usage /mnt/data

    8. Performance Tuning

    ext4 Tuning

    ext4 mount options for performance
    # /etc/fstab — optimized ext4
    /dev/vdb /mnt/data ext4 defaults,noatime,commit=60 0 2
    
    # noatime  — don't update access time on reads (big improvement)
    # commit=60 — flush data every 60s instead of 5s (less disk I/O)

    XFS Tuning

    XFS mount options for performance
    # /etc/fstab — optimized XFS
    /dev/vdb /mnt/data xfs defaults,noatime,logbufs=8,logbsize=256k 0 0
    
    # noatime    — skip access time updates
    # logbufs=8  — more in-memory log buffers
    # logbsize=256k — larger log buffer size

    Btrfs Tuning

    Btrfs mount options
    # /etc/fstab — optimized Btrfs
    /dev/vdb /mnt/data btrfs defaults,noatime,compress=zstd:3,space_cache=v2 0 0
    
    # compress=zstd:3 — zstd compression at level 3 (good balance)
    # space_cache=v2 — improved free space tracking
    # noatime        — skip access time updates
    
    # Disable COW for database directories (run BEFORE writing data)
    chattr +C /mnt/data/mysql

    I/O Scheduler

    Check and set I/O scheduler
    # Check current scheduler
    cat /sys/block/vda/queue/scheduler
    
    # For NVMe/SSD (most cloud VPS)
    echo "none" | sudo tee /sys/block/vda/queue/scheduler
    
    # For HDD
    echo "mq-deadline" | sudo tee /sys/block/vda/queue/scheduler

    9. Distribution Defaults

    Cloud images on RamNode use the filesystem default for each distribution:

    DistributionDefault FSNotes
    Ubuntu 22.04 / 24.04ext4Proven default, no changes needed
    Debian 12 / 13ext4Proven default, no changes needed
    AlmaLinux 9XFSRHEL default since RHEL 7
    Rocky Linux 9XFSRHEL-compatible default
    Fedora 39+BtrfsWith snapshots via snapper
    openSUSEBtrfsWith snapshots + YaST integration

    💡 Tip: You don't need to change the root filesystem. The default is fine for most workloads. Filesystem choice matters most for additional volumes like block storage where you control the formatting.