Linux filesystem comparison: ext4 (universal default), XFS (high throughput), Btrfs (snapshots + compression), ZFS (enterprise reliability). Formatting, tuning, and repair commands.
ext4
ext4 โ Extended Filesystem 4
| Property | Value |
|---|---|
| Max file size | 16 TB |
| Max volume size | 1 EB |
| Journaling | Yes โ data, ordered (default), writeback modes |
| Snapshots | No โ use LVM snapshots externally |
| Online shrink | No โ must unmount to shrink |
| Online grow | Yes (resize2fs while mounted) |
| Default on | Debian, Ubuntu, and most general-purpose distros |
| Best for | General purpose, VMs, boot partitions, broad compatibility |
ext4 commands
| Command | Description |
|---|---|
| mkfs.ext4 /dev/sdb1 | Format with ext4 |
| mkfs.ext4 -L mydata /dev/sdb1 | Format with label |
| mkfs.ext4 -b 4096 -j /dev/sdb1 | Specify block size (4096 = default) |
| tune2fs -l /dev/sdb1 | Show superblock (UUID, features, mount count) |
| tune2fs -L newlabel /dev/sdb1 | Set filesystem label |
| tune2fs -c 30 /dev/sdb1 | Force fsck every 30 mounts |
| tune2fs -i 6m /dev/sdb1 | Force fsck every 6 months |
| tune2fs -e remount-ro /dev/sdb1 | Remount read-only on error (safe default) |
| e2fsck -f /dev/sdb1 | Force check (must be unmounted) |
| e2fsck -p /dev/sdb1 | Auto-repair without interactive prompts |
| resize2fs /dev/data-vg/lv | Grow to fill LV (online) |
| resize2fs /dev/sdb1 30G | Shrink to 30 GB (unmounted) |
| dumpe2fs /dev/sdb1 | Full superblock + group descriptor dump |
| debugfs /dev/sdb1 | Interactive ext2/3/4 debugger (recover deleted files) |
XFS
XFS properties
| Property | Value |
|---|---|
| Max file size | 8 EB |
| Max volume size | 8 EB |
| Journaling | Yes โ metadata only by default (fast) |
| Online shrink | No โ cannot shrink XFS |
| Online grow | Yes (xfs_growfs while mounted) |
| Delayed allocation | Yes โ batches writes for efficiency |
| Default on | RHEL, CentOS, AlmaLinux, Rocky Linux |
| Best for | Large files, databases, high-throughput I/O, media storage |
XFS commands
| Command | Description |
|---|---|
| mkfs.xfs /dev/sdb1 | Format with XFS |
| mkfs.xfs -L mydata /dev/sdb1 | Format with label |
| mkfs.xfs -f /dev/sdb1 | Force overwrite existing filesystem |
| xfs_info /mount/point | Filesystem info (block size, allocation groups) |
| xfs_growfs /mount/point | Grow to fill block device (must be mounted) |
| xfs_repair /dev/sdb1 | Repair XFS filesystem (must be unmounted) |
| xfs_repair -n /dev/sdb1 | Dry-run check, no changes |
| xfs_check /dev/sdb1 | Check consistency (older, xfs_repair preferred) |
| xfs_fsr /mount/point | Defragment XFS (online) |
| xfs_db -r /dev/sdb1 | Interactive debugger (read-only) |
| xfs_admin -l /dev/sdb1 | Show label |
| xfs_admin -L newlabel /dev/sdb1 | Set label (unmounted) |
| xfs_quota -x -c 'report -h' /mount | Show quota report |
Btrfs
Btrfs โ B-tree Filesystem properties
| Property | Value |
|---|---|
| Max file size | 16 EB |
| Max volume size | 16 EB |
| Snapshots | Yes โ native, instant, space-efficient (Copy-on-Write) |
| Built-in RAID | RAID 0, 1, 10, 5, 6 (RAID 5/6 still experimental) |
| Compression | zlib, lzo, zstd โ transparent, per-file or per-mount |
| Checksums | CRC32C per block โ detects silent data corruption |
| Online shrink | Yes |
| Subvolumes | Independent filesystem trees within the same volume |
| Default on | openSUSE, Fedora (since F33), SteamOS |
| Best for | Desktop Linux, NAS, systems needing snapshots and compression |
Btrfs commands
| Command | Description |
|---|---|
| mkfs.btrfs /dev/sdb1 | Format with Btrfs |
| mkfs.btrfs -L mydata /dev/sdb1 | Format with label |
| mkfs.btrfs -d raid1 -m raid1 /dev/sdb /dev/sdc | RAID 1 across two drives |
| btrfs filesystem show /mount | Filesystem info |
| btrfs filesystem df /mount | Space usage by type (data, metadata) |
| btrfs filesystem resize max /mount | Grow to fill block device (online) |
| btrfs filesystem resize -10G /mount | Shrink by 10 GB (online) |
| btrfs subvolume create /mount/vol | Create a subvolume |
| btrfs subvolume list /mount | List all subvolumes |
| btrfs subvolume snapshot /mount/vol /mount/vol_snap | Create read-write snapshot |
| btrfs subvolume snapshot -r /mount/vol /mount/vol_snap | Create read-only snapshot |
| btrfs subvolume delete /mount/vol_snap | Delete snapshot |
| btrfs scrub start /mount | Verify all block checksums (background) |
| btrfs scrub status /mount | Check scrub progress |
| btrfs balance start /mount | Rebalance data across drives |
| btrfs check /dev/sdb1 | Check consistency (unmounted) |
Enable compression in fstab: compress=zstd or compress=zstd:3 (level 1โ22). Per-file: chattr +c file or btrfs property set file compression zstd.
ZFS (OpenZFS)
ZFS properties
| Property | Value |
|---|---|
| Snapshots | Instant, space-efficient, unlimited |
| RAIDZ | RAIDZ1 (RAID 5 equiv), RAIDZ2 (RAID 6), RAIDZ3 |
| Compression | lz4 (default), gzip, zstd โ per dataset |
| Deduplication | Yes โ RAM-intensive (DDT table) |
| Checksums | End-to-end, SHA256/Blake3 โ self-healing |
| ARC cache | Adaptive Replacement Cache โ in RAM |
| Default on | FreeBSD, TrueNAS, Proxmox (optional) |
| Best for | NAS, mission-critical data, storage servers |
| RAM minimum | 1 GB per 1 TB storage (ARC sizing rule of thumb) |
ZFS commands
| Command | Description |
|---|---|
| apt install zfsutils-linux | Install ZFS on Ubuntu/Debian |
| zpool create mypool /dev/sdb /dev/sdc | Create striped pool (RAID 0) |
| zpool create mypool mirror /dev/sdb /dev/sdc | Mirror pool (RAID 1) |
| zpool create mypool raidz /dev/sdb /dev/sdc /dev/sdd | RAIDZ1 pool (min 3 drives) |
| zpool status | Pool health, degraded drives |
| zpool status -v | Verbose โ shows error counts |
| zpool list | Pool size and usage |
| zpool scrub mypool | Verify all checksums (runs in background) |
| zfs list | All datasets and their sizes |
| zfs create mypool/data | Create a dataset |
| zfs set compression=lz4 mypool/data | Enable compression on dataset |
| zfs set quota=100G mypool/data | Set quota on dataset |
| zfs snapshot mypool/data@snap1 | Create a snapshot |
| zfs list -t snapshot | List all snapshots |
| zfs rollback mypool/data@snap1 | Roll dataset back to snapshot |
| zfs clone mypool/data@snap1 mypool/clone | Writable clone from snapshot |
| zfs send mypool/data@snap1 | ssh host zfs receive pool/data | Replicate dataset to remote host |
| zfs destroy mypool/data@snap1 | Delete a snapshot |
Comparison
Feature matrix
| Feature | ext4 | XFS | Btrfs | ZFS |
|---|---|---|---|---|
| Snapshots | No | No | Yes (CoW) | Yes (CoW) |
| Built-in RAID | No | No | Yes | Yes (RAIDZ) |
| Compression | No | No | Yes | Yes |
| Checksums | No | No | Yes | Yes (e2e) |
| Deduplication | No | No | Limited | Yes |
| Online shrink | No | No | Yes | No |
| Online grow | Yes | Yes | Yes | Yes |
| Subvolumes | No | No | Yes | Yes (datasets) |
| Maturity / stability | โ โ โ โ โ | โ โ โ โ โ | โ โ โ โ โ | โ โ โ โ โ |
| RAM overhead | Very low | Very low | Low | High (ARC) |
| Linux kernel | Mainline | Mainline | Mainline | DKMS module |
| Default distro | Ubuntu/Debian | RHEL/Fedora | openSUSE/Fedora | FreeBSD/TrueNAS |
When to choose
| Use case | Recommended FS | Reason |
|---|---|---|
| Boot partition | ext4 | Maximum compatibility with bootloaders |
| General server | ext4 or XFS | Proven, simple, no surprises |
| Database (MySQL, Postgres) | XFS or ext4 | Consistent write performance, no CoW overhead |
| Large files (video, backups) | XFS | Excellent at sequential I/O and large extents |
| Desktop with snapshots | Btrfs | Native snapshots before upgrades, compression |
| NAS with data integrity | ZFS | End-to-end checksums, self-healing, RAIDZ |
| Container host | Btrfs or ZFS | Efficient layer snapshots (Docker, LXC) |
| Limited RAM server | ext4 or XFS | ZFS/Btrfs need more RAM for metadata |
Common utilities
Universal filesystem tools
| Command | Description |
|---|---|
| blkid | Show UUID, type, and label of all block devices |
| lsblk -f | Block device tree with filesystem info |
| file -s /dev/sdb1 | Detect filesystem type on a raw device |
| fsck /dev/sdb1 | Check and repair filesystem (generic wrapper) |
| fdisk -l | Partition table and sizes |
| parted /dev/sdb print | Partition info (GPT-aware) |
| lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT,UUID | Custom lsblk columns |