Signal9Signal9 — home
online
all lessons

Which Filesystem, and Why? ext4 vs XFS vs btrfs/ZFS

Intermediate30 min5 steps
What you'll learn
  • See the filesystem type behind any mount with df -T, stat -f, and /proc/filesystems
  • Explain journaling (ext4, XFS) and why it protects metadata across a crash
  • Explain copy-on-write (btrfs, ZFS) and what snapshots and checksums buy you — and cost you
  • Choose ext4 vs XFS vs btrfs/ZFS for a given job, and name each one's real trade-off
  • Connect copy-on-write back to why shred is unreliable there
  1. One kernel, many filesystems

    See that the filesystem is a choice, and learn to read which one is in use.

    A filesystem is the on-disk format that turns a raw block device into files and directories — how inodes, data blocks, free space, and metadata are laid out. Linux does not have one filesystem; it supports many, and which one a given volume uses is a choice made when the volume is formatted. The reason you can ignore that choice most of the time is the kernel's VFS (Virtual File System) layer: ls, cp, cat, open() all talk to VFS, and VFS talks to whichever filesystem driver is underneath. So the commands are identical on ext4, XFS, or btrfs — the differences are in durability, performance, and features, not in how you use them day to day.

    That is exactly why the choice is easy to make blindly and worth understanding. The big three you will meet on Linux are ext4 and XFS (both journaling filesystems) and btrfs/ZFS (both copy-on-write). Before comparing them, learn to answer 'what am I even on?' — because the right first move when tuning or troubleshooting storage is to identify the filesystem type.

    df -T
    Filesystem     Type     1K-blocks    Used Available Use% Mounted on
    /dev/root      ext4      20510288 6200104  14293800  31% /
    tmpfs          tmpfs       200000       0    200000   0% /dev/shm
    df -T adds a Type column to the familiar disk-usage report, so you can see the filesystem behind every mount at a glance — here / is ext4. This is usually the fastest 'what am I on?' check. Note tmpfs too: not every mount is a disk filesystem — tmpfs lives in RAM.
    stat -f -c 'type=%T  blocks=%b  free=%f' /
    type=ext2/ext3  blocks=5127572  free=3573450
    stat -f reports on the filesystem holding a path (the -f), not the file. %T prints the type as the kernel names it (the ext2/3/4 family shares a driver, so it may read ext2/ext3). Handy when you have a path but not the mount point in front of you.
    cat /proc/filesystems
    nodev	sysfs
    nodev	tmpfs
    nodev	proc
    	ext4
    	xfs
    	fuseblk
    The filesystem types this kernel can mount. Entries marked nodev are virtual (no backing device — proc, sysfs, tmpfs); the rest are real on-disk formats the kernel has drivers for. If a type isn't listed, you can't mount it until its module is loaded — a useful check before reaching for btrfs or ZFS.
  2. Journaling: ext4 and XFS

    Understand the journal and the practical split between ext4 and XFS.

    A journaling filesystem keeps a small on-disk log — the journal — and writes its intent there before it changes the real metadata: 'I am about to update these inodes and this directory.' If power is lost mid-write, the filesystem replays (or discards) the journal on the next mount, so it comes back consistent in seconds instead of needing a long full scan. The journal mostly protects metadata (the structure), which is why a crash can still lose the contents of a file you were writing even though the filesystem itself stays sound. ext4 and XFS both work this way.

    The practical split between them:

    • ext4 is the mature, general-purpose default. It is rock-solid, well understood, and — usefully — it can be grown or shrunk. If you want one boring filesystem that is right for a root disk, a laptop, or a small server, it is ext4.
    • XFS is built for large files and high parallelism: big media, databases, many CPUs writing at once. It scales to huge volumes and sustains heavy concurrent I/O better than ext4, which is why it is the default on RHEL and its rebuilds. The catch that surprises people: XFS can grow but cannot shrink — plan sizes accordingly.

    Rule of thumb: unsure or small → ext4; big files, databases, RHEL, or many parallel writers → XFS.

    Example — not runnable on your lab box

    mkfs.xfs /dev/sdb1
    meta-data=/dev/sdb1  isize=512  agcount=4, agsize=655360 blks
    data     =           bsize=4096  blocks=2621440, imaxpct=25
    …
    Successfully created XFS filesystem
    Formatting a partition as XFS (illustrative — it needs a real spare device, so it does not run in this lesson box). mkfs.ext4 /dev/sdb1 would make ext4 instead. The agcount (allocation groups) is XFS's trick for parallelism: independent regions the kernel can allocate into concurrently, which is where its multi-writer performance comes from.
  3. Copy-on-write: btrfs and ZFS

    Understand CoW and the features (and costs) it enables.

    btrfs and ZFS take a different approach: copy-on-write (CoW). They never overwrite data in place. When you change a block, the new version is written to a free location, and only once it is safely on disk does the filesystem flip its pointers to the new block. The old block is left until it is no longer referenced. That one design decision buys three things journaling filesystems don't have natively:

    • Snapshots that are nearly free. Because old blocks are only reclaimed when unreferenced, a snapshot is just 'keep pointing at the old blocks too.' You can snapshot a whole filesystem in an instant before a risky upgrade and roll back if it goes wrong.
    • Checksums on data, not just metadata. Every block is checksummed, so silent corruption ('bit rot') is detected on read — and on a mirror, repaired from the good copy. Journaling filesystems trust the disk to return what it stored; CoW filesystems verify it.
    • Built-in volume management. ZFS especially rolls RAID, pooling, and the filesystem into one layer, so you don't stack LVM + mdadm + a filesystem separately.

    None of this is free. CoW filesystems use more RAM (ZFS notably so), the never-overwrite model fragments write-heavy workloads like databases, they are more complex to operate, and ZFS ships out-of-tree on Linux for licensing reasons (it is not in the mainline kernel, so it is an add-on package rather than a built-in). btrfs is in the mainline kernel and is the lighter-weight way to get snapshots and checksums.

    Example — not runnable on your lab box

    btrfs subvolume snapshot /data /data/.snap-2026-09-22
    Create a snapshot of '/data' in '/data/.snap-2026-09-22'
    An instant, space-cheap snapshot on btrfs (illustrative — needs a btrfs volume). At creation it shares all blocks with the live filesystem and only diverges as data changes, so it costs almost nothing until you start writing. This is the CoW payoff: a safety net you can take before any risky change and discard or roll back to. ZFS's equivalent is zfs snapshot tank/data@2026-09-22.
  4. The deletion caveat CoW brings

    Connect copy-on-write back to why shred is unreliable there.

  5. Choosing, in one breath

    Pick the right filesystem for a job and name its trade-off.

    Put it together as a decision you can make quickly:

    • Default / unsure / needs to shrink → ext4. Mature, predictable, resizable both ways. The safe answer for a root disk or a general server, and the one to reach for when you have no special reason to do otherwise.
    • Large files, databases, heavy parallel I/O, RHEL → XFS. Scales and sustains concurrency better; it is RHEL's default for good reason. Remember it grows but never shrinks.
    • You want snapshots and data integrity and can pay for them → btrfs or ZFS. Cheap snapshots, checksums that catch corruption, integrated volume management — at the cost of RAM, complexity, CoW fragmentation on write-heavy loads, and (for ZFS) an out-of-tree module. btrfs is the in-kernel, lighter option; ZFS is the heavyweight with the deepest storage features.

    And the reassuring part: whichever you pick, the everyday commands don't change — VFS hides the difference, so ls, cp, find, and permissions all behave identically. You choose a filesystem for its durability, performance, and features, then use the machine exactly as you always have.

    df -T; stat -f -c 'root fs = %T' /
    Filesystem     Type   1K-blocks    Used Available Use% Mounted on
    /dev/root      ext4    20510288 6200104  14293800  31% /
    root fs = ext2/ext3
    The two read-only checks together — the practical habit worth keeping. Before you tune mount options, plan a resize, or reach for snapshots, confirm the filesystem type first (here ext4). The choice of filesystem determines which of those moves are even available: you can shrink this ext4; you could not shrink an XFS; and only on btrfs/ZFS would snapshot be on the table.

    Check yourself

    You need a filesystem for a large database server on RHEL, with heavy parallel writes. ext4, XFS, or btrfs — and what's the one catch to remember?

Recap
  • Linux supports many filesystems and VFS hides the difference, so ls/cp/permissions are identical across them; you choose a filesystem for durability, performance, and features. Identify the one in use with df -T, stat -f, and /proc/filesystems.
  • Journaling (ext4, XFS) logs its intent before changing metadata, so a crash recovers in seconds. ext4 is the mature, resizable general default; XFS scales for large files and parallel I/O and is RHEL's default, but it grows and never shrinks.
  • Copy-on-write (btrfs, ZFS) never overwrites in place, which buys near-free snapshots, data checksums that catch bit-rot, and built-in volume management — at the cost of RAM, complexity, CoW fragmentation on write-heavy loads, and (ZFS) an out-of-tree module.
  • Because CoW never overwrites in place, shred is unreliable on btrfs/ZFS (as on SSDs) — use full-disk encryption plus key destruction. Choose: ext4 by default, XFS for big/parallel/RHEL, btrfs/ZFS when snapshots and integrity are worth the overhead.