The problem many sysadmins face when choosing a filesystem
When I first started as a sysadmin, I once spent an entire afternoon debugging an issue simply because I hadn’t read the logs carefully enough — a MySQL database server was experiencing severe performance degradation after being migrated to a new server. The root cause turned out to be surprisingly simple: the new server was using ext4 with default mount options, while the old server had been running XFS, carefully tuned for high random I/O workloads.
The default filesystem when installing most distros is ext4. Most people never question this — regardless of whether the server runs a database, file server, or streaming workload. But the question “ext4 or XFS?” might look simple on the surface; the answer depends entirely on the actual workload you’re running.
Why filesystems matter more than you think
A filesystem is more than just a place to store files. It determines how the kernel manages metadata, how journaling is handled, block allocation mechanisms, and caching strategies. For a database server processing thousands of transactions per second, the difference between filesystems can translate to 20–40% in real-world measured performance.
Before choosing, there are 4 factors to consider:
- Workload pattern: Sequential read/write (streaming, backup) or random I/O (database, VM disk)?
- File size: Many small files (mail server, web server) or fewer large files (video storage, backup)?
- Feature requirements: Do you need snapshots, compression, or integrated RAID?
- Storage type: Traditional HDD, SSD, or flash storage?
Breaking down each filesystem
ext4 — The reliable old friend
Installing Ubuntu on a server? ext4. CentOS? ext4. Debian? ext4 again. That’s no coincidence — this filesystem is stable, battle-tested over more than 15 years, and has the richest tooling support in the Linux ecosystem.
Strengths:
- Solid journaling with fast, reliable crash recovery
- Mature toolset:
fsck,debugfs,tune2fs— comprehensive documentation and plenty of answers on StackOverflow - Stable performance on both HDD and SSD
- Low overhead, suitable for servers with limited RAM (works well under 4GB)
Limitations:
- No native snapshots — you need LVM or a separate storage layer for snapshots
- Performance degrades when directories contain hundreds of thousands of small files
- No built-in compression or deduplication
Format and mount ext4 with optimized options for SSD:
# Format with lazy initialization disabled (faster for SSD)
mkfs.ext4 -E lazy_itable_init=0,lazy_journal_init=0 /dev/sdb1
# Mount with optimized options — noatime reduces writes, discard enables TRIM
mount -o noatime,discard /dev/sdb1 /data
# Add to /etc/fstab
/dev/sdb1 /data ext4 defaults,noatime,discard 0 2
# Tune journal commit interval (default 5s, increase to reduce I/O)
tune2fs -o journal_data_writeback /dev/sdb1
XFS — The go-to choice for databases and heavy workloads
Red Hat chose XFS as the default filesystem starting with RHEL 7 — not without reason. Designed from the ground up for high performance with large files and parallel I/O from multiple concurrent processes, this is why XFS consistently dominates real-world database benchmarks.
Standout strengths:
- Excellent performance with large files and sequential I/O
- Separate metadata journaling that doesn’t impact data throughput
- Online resize — expand the filesystem while mounted, no downtime required
- Delayed allocation significantly reduces fragmentation
- Concurrent writes from multiple processes are noticeably better than ext4, especially with 8+ simultaneous threads
Limitations:
- Cannot shrink the filesystem — you can only grow it, never reduce it. Plan your capacity carefully before formatting
- No native compression or deduplication
# Format XFS with appropriate sector size for enterprise SSDs
mkfs.xfs -f -s size=4096 /dev/sdb1
# Mount with options for database servers
mount -o noatime,logbsize=256k,largeio /dev/sdb1 /data
# Check and repair XFS (unmount first)
xfs_repair /dev/sdb1
# Grow XFS online (while the filesystem is mounted)
xfs_growfs /data
# View detailed filesystem information
xfs_info /data
Btrfs — Feature-rich, but not for everyone
Fedora 33 switched to Btrfs as its default — a fairly bold decision at the time. openSUSE had adopted Btrfs even earlier. Both bet on its snapshot capabilities and self-healing properties. Looking back, it was the right call.
Genuinely differentiating features:
- Native snapshots: Instant snapshots that consume no additional space immediately, thanks to copy-on-write
- Inline compression: Transparent LZO/zlib/zstd — in practice saves 20–40% of disk space for text and log files
- Subvolumes: More flexible management than traditional partitions, no need to pre-allocate space
- Data + metadata checksums: Automatic bit rot detection — something neither ext4 nor XFS can do
Things to watch out for before using in production:
- Btrfs RAID 5/6 has known bugs — do not use in production, use mdadm or ZFS instead
- Pure random write performance is roughly 10–15% worse than ext4/XFS in benchmarks
btrfsckis less mature thane2fsck, and recovery is more complex in cases of severe corruption
# Format Btrfs
mkfs.btrfs -L "data-volume" /dev/sdb1
# Mount with zstd compression (better ratio, faster than zlib)
mount -o compress=zstd:3,noatime /dev/sdb1 /data
# Create a subvolume (like a logical partition, but more flexible)
btrfs subvolume create /data/www
btrfs subvolume create /data/db
# Read-only snapshot (instant, no extra space consumed initially)
btrfs subvolume snapshot -r /data/www /data/snapshots/www-$(date +%Y%m%d)
# List all subvolumes and snapshots
btrfs subvolume list /data
# Check usage with compression ratio
btrfs filesystem df /data
btrfs filesystem usage /data
F2FS — Purpose-built for flash storage
If you’ve never encountered F2FS on an enterprise server, that’s completely normal. Samsung developed this filesystem to solve a specific problem: NAND flash suffers from high write amplification and uneven wear patterns. F2FS optimizes write patterns to extend device lifespan.
Strengths:
- Reduces write amplification on NAND flash, significantly extending the lifespan of SSDs and eMMC devices
- Better random I/O performance than ext4 on consumer-grade SSDs (typically 10–20% in benchmarks)
- Automatic hot/cold data separation that reduces fragmentation over time
Limitations:
- Only suitable for flash storage — performance on HDD is worse than ext4
- Far fewer tools and documentation compared to ext4/XFS
- Not widely used in enterprise server environments
# Install F2FS tools (Ubuntu/Debian)
apt install f2fs-tools
# Format F2FS
mkfs.f2fs /dev/sdb1
# Mount
mount -t f2fs /dev/sdb1 /data
# View filesystem info
dump.f2fs /dev/sdb1
Real-world mapping: which filesystem for which scenario
From hands-on operational experience, here’s how I map filesystems to workloads:
| Scenario | Recommended Filesystem | Primary Reason |
|---|---|---|
| General purpose Linux server | ext4 | Stable, low risk, best tool support |
| Database server (MySQL/PostgreSQL) | XFS | High concurrent I/O, separate metadata journal |
| NAS / Storage server needing snapshots | Btrfs | Snapshots + compression save significant space |
| Desktop Linux (Fedora/openSUSE) | Btrfs | Snapshot before updates, easy rollback |
| Consumer SSD / flash devices | F2FS | Optimized flash lifespan, better random I/O |
| High-throughput log / streaming server | XFS | Fast sequential writes, effective delayed allocation |
Mixing filesystems per workload — instead of forcing one to do it all
Production servers rarely have a single uniform workload. A server running both a database and backups needs two different filesystems — there’s no need to squeeze everything into one. Here’s how I typically lay it out:
# View current layout
lsblk -f
# Example optimized layout for a database + backup server:
# /dev/sda1 ext4 / — Root: stable, easy to recover
# /dev/sdb1 xfs /var/lib/mysql — Database: high concurrent I/O
# /dev/sdc1 btrfs /backup — Backup: compression + snapshots
# Check mount options for all currently active filesystems
findmnt -t ext4,xfs,btrfs -o TARGET,SOURCE,OPTIONS
# Quick benchmark to compare before deciding
# (install fio: apt install fio)
fio --name=randwrite --ioengine=libaio --rw=randwrite \
--bs=4k --numjobs=4 --size=1G --runtime=30 \
--filename=/data/testfile --direct=1
The most expensive lesson I ever learned: never migrate a filesystem on a production server without thorough testing first. The time I moved a MySQL data partition from ext4 to XFS, I lost nearly 4 hours of downtime because I forgot to dump and verify all the data beforehand. Test on staging, benchmark with your actual workload — then, and only then, touch production.
My personal rule of thumb: ext4 for / (root), XFS for data disks running databases or heavy logging, Btrfs for storage servers that need snapshots and compression. F2FS only appears on my radar when working with pure flash storage — old laptops, Raspberry Pi, embedded devices.

