A filesystem is the scheme an operating system uses to lay out files on a disk — how it tracks where each file lives, what it's named, who owns it, and whether the disk can recover after a power cut. Pick the wrong one and you hit a wall: a 5 GB video that won't copy to a USB stick, a drive your Mac can't write to, a server that loses data on a crash. This guide is a complete, cross-platform tour: what every common filesystem is good for, and exactly how to create, mount, check, and maintain one on Linux, Windows, macOS, and BSD.
You don't need to read it front to back. Use the table of contents to jump to the filesystem or the task you care about. Wherever a command can destroy data, there's a warning — read those.
What a filesystem actually is
Think of a disk as a huge wall of numbered boxes (blocks), each a few kilobytes. On its own that wall has no notion of "files" — it's just boxes. A filesystem is the card catalog laid over those boxes: a structure that says "the file budget.xlsx is 40 KB, owned by you, lives in boxes 12, 13 and 980, and was changed last Tuesday." On most Unix-style systems that per-file record is called an inode.
The interesting differences between filesystems come down to a few design choices:
- Journaling. Before changing the catalog, the filesystem writes down what it's about to do in a small log (the journal). If the power dies mid-write, it replays or rolls back the log on the next boot instead of leaving a corrupt mess. ext4, XFS, NTFS, and HFS+ are journaling filesystems.
- Copy-on-write (CoW). Instead of overwriting data in place, the filesystem writes the new version to free space and only then flips a pointer. This makes crashes safe almost for free and makes instant snapshots possible. Btrfs, ZFS, APFS, and ReFS are copy-on-write.
- Checksums. Some filesystems store a checksum of every block and verify it on read, so silent corruption ("bit rot") is detected — and, with redundancy, repaired. ZFS and Btrfs do this for data; most others only protect metadata, if anything.
- Block size, max file size, max volume size. The limits that decide whether a filesystem can hold a 100 GB file or a 100 TB array at all.
Tip: the safe modern defaults are ext4 (Linux desktops/servers that want boring reliability), Btrfs or ZFS (when you want snapshots and checksums), NTFS (Windows), APFS (macOS), and exFAT (a USB stick shared between all three). If you remember nothing else, remember that line.
A field guide to every filesystem
Here is the bird's-eye comparison, followed by a short capsule on each. "CoW" = copy-on-write; "Journal" = journaling; sizes are practical maximums, not the absolute theoretical ones.
| Filesystem | Home OS | Max file | Crash safety | Snapshots | Best for |
|---|---|---|---|---|---|
| ext4 | Linux | 16 TB | Journal | Via LVM | The reliable default for Linux root/data |
| XFS | Linux | 8 EB | Journal | Via LVM | Large files, heavy parallel I/O, big servers |
| Btrfs | Linux | 16 EB | CoW + checksums | Built-in | Snapshots, self-healing, flexible volumes |
| ZFS | BSD/Linux/illumos | 16 EB | CoW + checksums | Built-in | NAS, servers, anything where data integrity is king |
| F2FS | Linux | 4 TB | Journal-ish | No | Phones, SD cards, raw flash |
| bcachefs | Linux | 16 EB | CoW + checksums | Built-in | Newer CoW alternative to Btrfs/ZFS |
| UFS / FFS | BSD | large | Soft-updates/journal | Via snapshots | The classic BSD default |
| NTFS | Windows | 256 TB | Journal | VSS | The Windows default for system + data |
| ReFS | Windows | huge | CoW + checksums | Block clone | Storage Spaces, large data volumes (not boot) |
| APFS | macOS | 8 EB | CoW | Built-in | The macOS default (SSD-optimised) |
| HFS+ | macOS (legacy) | 8 EB | Journal | No | Old Macs and spinning-disk Time Machine drives |
| exFAT | cross-platform | 16 EB | None | No | USB sticks/SD cards shared across OSes |
| FAT32 | cross-platform | 4 GB | None | No | UEFI boot partitions, ancient devices |
| UDF | cross-platform | 16 EB | None | No | Optical discs; rare as a universal disk format |
Linux-native filesystems
ext4 — the boring, excellent default on most Linux distributions. Journaling, rock-solid, fast enough for almost everyone, and the one with the most mature repair tools. If you have no special requirement, this is the right answer.
XFS — a high-performance journaling filesystem that shines with large files and many simultaneous writers (databases, media servers, Red Hat's default). It can grow but cannot shrink, so size partitions with that in mind.
Btrfs — copy-on-write with built-in snapshots, data checksums, transparent compression, and the ability to span multiple disks. Great when you want to snapshot before a risky upgrade and roll back if it breaks. Use its built-in RAID 0/1/10; avoid its parity RAID 5/6 for important data.
ZFS (OpenZFS) — the gold standard for data integrity: checksummed end to end, self-healing with redundancy, snapshots, send/receive replication, and built-in volume management. It's not in the mainline Linux kernel for licensing reasons, so it's installed as a separate package. It likes RAM and whole disks.
F2FS (Flash-Friendly FS) — designed for the way raw NAND flash actually works; common on Android phones and a good pick for SD cards and cheap USB flash where you control both ends.
bcachefs — a newer copy-on-write filesystem aiming to combine Btrfs's flexibility with ZFS-like reliability. Promising but young; fine to experiment with, think twice before trusting irreplaceable data to it.
JFS and ReiserFS — historical Linux journaling filesystems. You may meet them on old systems; don't choose them for anything new. ReiserFS in particular is removed from current kernels.
BSD filesystems
UFS / FFS — the traditional BSD filesystem, hardened over decades. FreeBSD uses "soft updates" (and optional journaling) to stay consistent across crashes. Light, dependable, and still the default for small/simple installs.
ZFS on FreeBSD — FreeBSD ships ZFS as a first-class citizen and it's the recommended choice for anything serious: it's the same OpenZFS as on Linux, with the same checksums, snapshots, and pools. Many people run FreeBSD specifically because ZFS is so well integrated.
Windows filesystems
NTFS — the Windows default since the XP era: journaling, permissions (ACLs), compression, encryption (EFS), large files. Use it for your system drive and any internal data drive. Linux and macOS can read NTFS easily; writing needs an extra driver (see Mounting).
ReFS (Resilient File System) — Microsoft's copy-on-write filesystem with checksums and automatic repair when paired with Storage Spaces redundancy. It's for large data volumes, not your boot drive (you can't boot from it), and it's only on certain Windows editions.
FAT32 and exFAT — see Removable / interchange below; FAT32 is also what UEFI firmware reads, so the EFI System Partition is FAT32.
macOS filesystems
APFS (Apple File System) — the default since macOS High Sierra: copy-on-write, instant snapshots (Time Machine on modern macOS uses them), strong SSD optimisation, native encryption, and space-sharing "containers" where several volumes draw from one free-space pool. Use it for any internal SSD.
HFS+ (Mac OS Extended) — the previous default. Still the right choice for an external spinning hard drive used with Time Machine on older systems, and for compatibility with very old Macs. Journaling, but no snapshots or checksums.
Removable and interchange formats
exFAT — the modern answer to "a USB stick or SD card that Windows, macOS, and Linux can all read and write." No 4 GB file limit, no journaling (so always eject cleanly), and no Unix permissions. This is what you want for big media files shuttled between machines.
FAT32 — universally readable by everything ever made, including game consoles, cameras, car stereos, and UEFI firmware. The catch: no single file larger than 4 GB and a ~2 TB volume ceiling. Use it for tiny/old devices and EFI partitions; use exFAT for everything else removable.
UDF — designed for optical media (DVDs, Blu-ray). It can format USB drives in a way many systems read, but support is inconsistent enough that exFAT is the better cross-platform choice today.
Pseudo and network filesystems
Not everything called a "filesystem" lives on a disk:
- tmpfs — a filesystem that lives in RAM. Fast, and wiped on reboot. Linux uses it for
/tmp,/run, and/dev/shm. - swap — not a filesystem at all but a disk area used as overflow for RAM. Created with
mkswap, enabled withswapon. - NFS and SMB/CIFS — network filesystems: you mount a folder that physically lives on another machine. NFS is the Unix-world standard; SMB (Samba) is the Windows-world standard and what most NAS boxes speak. The on-disk format of the server is irrelevant to the client.
Choosing one: when to use what
Match the job to the filesystem:
- A normal Linux desktop or server, no special needs → ext4. It just works and is the easiest to repair.
- You want snapshots / rollback before risky updates → Btrfs (single machine) or ZFS (servers/NAS).
- A file server / NAS holding data you can't lose → ZFS with redundancy. Checksums + self-healing are the whole point.
- Huge files, databases, lots of parallel I/O on Linux → XFS.
- A phone, SD card, or raw flash you control → F2FS.
- A Windows internal drive → NTFS (boot/system or data); ReFS only for big non-boot data pools with Storage Spaces.
- A Mac internal SSD → APFS. An external spinning Time Machine disk on an older Mac → HFS+.
- A USB stick / SD card shared across Windows, macOS, and Linux → exFAT. If it must work with very old or embedded gear → FAT32 (mind the 4 GB file limit).
- A UEFI boot/EFI System Partition → FAT32. The firmware requires it.
Note: copy-on-write filesystems (Btrfs, ZFS, APFS, ReFS) trade a little raw speed and need a bit more care for enormous wins in safety and snapshots. Plain journaling filesystems (ext4, XFS, NTFS) are simpler and slightly faster for some workloads. Neither is "better" in the abstract — it depends on whether you value snapshots/integrity or simplicity/throughput.
Creating a filesystem
Creating ("formatting") a filesystem erases everything on the target. The single most important step is identifying the right device.
Warning: formatting the wrong disk is the classic, unrecoverable disaster. On Linux list devices with
lsblkand confirm by size and removable flag before you touch anything. On Windows/macOS confirm the disk number and name in the graphical tool first. When in doubt, unplug every other external drive.
Linux
Each filesystem has its own mkfs ("make filesystem") tool. Replace /dev/sdX1 with your real partition.
# ext4, with a volume label
sudo mkfs.ext4 -L mydata /dev/sdX1
# XFS
sudo mkfs.xfs -L mydata /dev/sdX1
# Btrfs
sudo mkfs.btrfs -L mydata /dev/sdX1
# F2FS
sudo mkfs.f2fs -l mydata /dev/sdX1
# FAT32
sudo mkfs.vfat -F 32 -n MYSTICK /dev/sdX1
# exFAT (needs exfatprogs)
sudo mkfs.exfat -n MYSTICK /dev/sdX1
ZFS doesn't format a partition — you give it whole disks and build a pool:
# a two-disk mirror named "tank"
sudo zpool create tank mirror /dev/sda /dev/sdb
# a dataset inside it
sudo zfs create tank/media
For swap: sudo mkswap /dev/sdX2 && sudo swapon /dev/sdX2.
BSD (FreeBSD)
Partition with gpart, then make the filesystem. UFS uses newfs; ZFS builds a pool just like on Linux.
# UFS with soft-updates
newfs -U /dev/da0p1
# ZFS mirror
zpool create tank mirror da0 da1
# a dataset
zfs create tank/data
Windows
Easiest is graphical: Disk Management (diskmgmt.msc) → right-click the volume → Format, pick NTFS or exFAT. From a terminal:
:: quick-format D: as NTFS
format D: /FS:NTFS /Q /V:MyData
:: exFAT for a USB stick
format E: /FS:exFAT /Q
For full control over partitions, diskpart (run as Administrator) does the same job; list disk first, and triple-check the disk number with select disk N before clean/format.
macOS
Graphical: Disk Utility → select the disk → Erase → choose APFS (internal SSD) or Mac OS Extended (Journaled) (HFS+) or exFAT (cross-platform). From Terminal:
# find the identifier, e.g. disk4
diskutil list
# whole disk to APFS
diskutil eraseDisk APFS MyData disk4
# exFAT USB stick
diskutil eraseDisk ExFAT MYSTICK MBRFormat disk4
Mounting and unmounting
"Mounting" attaches a filesystem to a location you can browse. Unmounting detaches it cleanly so buffered writes are flushed — always unmount/eject before unplugging, especially for exFAT/FAT which have no journal to recover from.
Linux
# see devices, types, UUIDs, mountpoints
lsblk -f
# mount once, manually
sudo mount /dev/sdX1 /mnt
# unmount
sudo umount /mnt
# confirm what's mounted where
findmnt /mnt
To mount automatically at boot, add a line to /etc/fstab keyed by UUID (stable across reboots, unlike /dev/sdX names). Get the UUID from lsblk -f or blkid:
UUID=1234-ABCD /data ext4 defaults,noatime 0 2
To mount NTFS or exFAT, install the helper packages (ntfs-3g, exfatprogs); modern kernels also have a built-in NTFS driver. Network shares: mount -t nfs server:/export /mnt or mount -t cifs //server/share /mnt -o user=me.
BSD (FreeBSD)
Same mount/umount idea, with BSD device names and an /etc/fstab that lists ufs partitions. ZFS datasets mount themselves based on their mountpoint property — no fstab entry needed:
# mount UFS
mount /dev/da0p1 /mnt
# ZFS mounts here automatically
zfs set mountpoint=/data tank/data
Windows
Windows mounts volumes automatically and gives them drive letters (C:, D:…). Manage them in Disk Management → Change Drive Letter and Paths, where you can also mount a volume into an empty NTFS folder instead of a letter. From a terminal, mountvol lists and assigns mount points. "Safely Remove Hardware" (or right-click → Eject in Explorer) is the unmount step for USB drives.
macOS
macOS auto-mounts disks into /Volumes when you plug them in. To do it by hand:
# mount a volume
diskutil mount disk4s2
# unmount (or drag to Trash / click Eject)
diskutil unmount disk4s2
# unmount every volume on a disk
diskutil unmountDisk disk4
macOS reads NTFS out of the box but won't write to it without third-party software; for a drive shared with Windows, format it exFAT instead.
Checking and repairing
Warning: never run a repair tool on a mounted, writable filesystem — unmount it first (or boot from other media). And if the disk is physically failing, image it first (e.g.
ddrescue) and repair the copy: a repair pass on dying hardware can finish the job of destroying your data.
Linux
Each filesystem has its own checker; unmount the target first (a scrub is the exception — it runs on a mounted filesystem).
# always unmount before an offline repair
sudo umount /dev/sdX1
# ext2 / ext3 / ext4 — force a full check & repair
sudo fsck.ext4 -f /dev/sdX1
# XFS — its own repair tool (fsck.xfs does nothing)
sudo xfs_repair /dev/sdX1
# Btrfs — inspect read-only first...
sudo btrfs check --readonly /dev/sdX1
# ...then scrub to verify checksums & self-heal (this one runs mounted)
sudo btrfs scrub start /data
# F2FS
sudo fsck.f2fs /dev/sdX1
# FAT12/16/32
sudo fsck.vfat -a /dev/sdX1
# exFAT (exfatprogs)
sudo fsck.exfat /dev/sdX1
# NTFS — quick fix; for a deep repair use Windows chkdsk
sudo ntfsfix /dev/sdX1
# bcachefs
sudo fsck.bcachefs /dev/sdX1
# ZFS — verify & repair the whole pool, then read the report
sudo zpool scrub tank
zpool status tank
Note the split: ext/F2FS/FAT/exFAT use a fsck.*; XFS uses its own xfs_repair; Btrfs and ZFS prefer an online scrub (which uses checksums to find and fix corruption) over an offline check.
BSD (FreeBSD)
# UFS (unmounted or single-user)
fsck_ufs /dev/da0p1
# FAT (msdosfs)
fsck_msdosfs /dev/da0s1
# exFAT — from the exfat-utils port
fsck.exfat /dev/da0s1
# NTFS — quick fix, from the fusefs-ntfs port
ntfsfix /dev/da0s1
# ZFS
zpool scrub tank
zpool status -v tank
Windows
chkdsk handles every Windows on-disk filesystem; pick the drive letter.
:: read-only scan (works on NTFS, FAT32 and exFAT)
chkdsk D:
:: fix errors (/f) and recover readable bad sectors (/r)
chkdsk D: /f /r
:: ReFS self-heals from Storage Spaces redundancy; this only scans
chkdsk R: /scan
:: repair corrupted Windows system files
sfc /scannow
If the volume is in use (like C:), chkdsk offers to run on the next reboot — accept that.
macOS
Graphical: Disk Utility → select the volume → First Aid (works on APFS, HFS+, exFAT, and FAT). From Terminal, either use diskutil or the per-filesystem checkers on an unmounted volume:
# First Aid on any supported volume
diskutil verifyVolume disk4s2
diskutil repairVolume disk4s2
# APFS
sudo fsck_apfs /dev/disk4s2
# HFS+
sudo fsck_hfs /dev/disk4s2
# exFAT
sudo fsck_exfat /dev/disk4s2
# FAT
sudo fsck_msdos /dev/disk4s2
For the system volume, boot into Recovery (or single-user) and run First Aid there, since it can't repair the disk it's running from.
Defrag and TRIM
Two different things people lump together:
- Defragmentation reorganises a file's scattered pieces to be contiguous. It mattered on spinning hard drives, where the head had to physically seek. On SSDs it is pointless and even harmful (extra writes, no seek penalty), and on copy-on-write filesystems it's mostly meaningless by design. Modern OSes only defrag actual HDDs, automatically.
- TRIM tells an SSD which blocks are no longer used so it can erase them ahead of time and stay fast. This is what you actually want to keep an SSD healthy — and every modern OS does it automatically. You rarely need to run it by hand.
Linux
TRIM is filesystem-agnostic — one fstrim covers every mounted filesystem that supports discard (ext4, XFS, Btrfs, F2FS, exFAT, NTFS). ZFS is the exception and uses its own command. Defrag, where it still applies, is per-filesystem.
# TRIM every mounted filesystem with discard support, now
sudo fstrim -av
# enable the weekly automatic TRIM timer (preferred over inline discard)
sudo systemctl enable --now fstrim.timer
# ZFS uses its own TRIM, not fstrim — trim the pool now...
sudo zpool trim tank
# ...and enable continuous autotrim
sudo zpool set autotrim=on tank
# Defrag is for HDDs only and pointless on SSDs:
# ext4
sudo e4defrag /path
# XFS
sudo xfs_fsr /path
# Btrfs (targeted)
sudo btrfs filesystem defragment -r /path
# F2FS is log-structured and defragments itself — nothing to run
You can also add the discard mount option for continuous TRIM, but the scheduled fstrim.timer is gentler and generally recommended over inline discard.
BSD (FreeBSD)
# UFS — enable TRIM on an existing filesystem (or use newfs -t at creation)
tunefs -t enable /dev/da0p1
# ZFS — trim the pool now...
zpool trim tank
# ...and enable continuous autotrim
zpool set autotrim=on tank
Neither UFS nor ZFS has (or needs) a manual defragmenter.
Windows
Optimize Drives (dfrgui) is smart and filesystem-agnostic: it retrims SSDs and defragments HDDs, on a schedule, for NTFS, ReFS, exFAT, and FAT volumes alike. To force it:
:: optimize correctly for the drive type — retrim SSDs, defrag HDDs
defrag C: /O
:: retrim an SSD volume specifically
defrag C: /L
macOS
APFS and HFS+ TRIM automatically on Apple SSDs, and macOS has no manual defragmenter (nor any need for one). The one thing you may run is enabling TRIM on a third-party SSD:
# enable TRIM for a non-Apple SSD (reboots afterwards)
sudo trimforce enable
Resizing, snapshots, and converting
Resizing. Growing is usually safe and often online; shrinking is riskier and not always supported. Always back up first.
# ext4: grow or shrink (shrink unmounted)
sudo resize2fs /dev/sdX1
# XFS: grow only — it cannot shrink
sudo xfs_growfs /mountpoint
# Btrfs: grow/shrink online
sudo btrfs filesystem resize +10G /mnt
# macOS APFS resize
diskutil apfs resizeContainer disk0s2 0
On Windows, use Disk Management → Shrink Volume / Extend Volume, or diskpart.
Snapshots. A snapshot is a frozen, near-instant point-in-time view you can roll back to. Built in on Btrfs (btrfs subvolume snapshot), ZFS (zfs snapshot tank/data@before-upgrade), APFS (tmutil localsnapshot), and via LVM on ext4/XFS, or VSS/ReFS on Windows.
Converting. A few one-way upgrades exist: btrfs-convert turns ext4 into Btrfs in place, and macOS converts HFS+ to APFS during install. Most other "conversions" really mean back up, reformat, restore.
Cross-platform gotchas
- FAT32 can't hold a file over 4 GB. One movie or disk image and you're stuck. Use exFAT or NTFS instead.
- Permissions don't survive FAT/exFAT. They store no Unix ownership or ACLs — fine for media, wrong for backups of a Linux system.
- Case sensitivity differs. ext4 is case-sensitive (
File≠file); NTFS and the default APFS are case-insensitive. Moving a project between them can collide or "lose" files that differ only in case. - NTFS write on macOS, exFAT/NTFS on Linux need extra drivers; the universally writable choice everywhere is exFAT.
- No journal means no safety net. exFAT/FAT corrupt easily if you yank the drive mid-write — eject properly, every time.
- The EFI System Partition is FAT32 on purpose; don't reformat it to something "better" or the machine won't boot.
Quick reference
Linux
- Create:
sudo mkfs.ext4 -L name /dev/sdX1· mount:sudo mount /dev/sdX1 /mnt· repair:sudo fsck.ext4 -f /dev/sdX1· TRIM:sudo fstrim -av - ZFS pool health:
zpool status· scrub:sudo zpool scrub tank
BSD
- Create:
newfs -U /dev/da0p1(UFS) /zpool create tank mirror da0 da1· repair:fsck -t ufs/zpool scrub· TRIM:zpool trim tank
Windows
- Create:
format D: /FS:NTFS /Q· repair:chkdsk D: /f /r· optimize/TRIM:defrag C: /O· system files:sfc /scannow
macOS
- Create:
diskutil eraseDisk APFS Name disk4· mount:diskutil mount disk4s2· repair:diskutil repairVolume disk4s2· TRIM/defrag: automatic, nothing to do
Pick-one cheat sheet: Linux default → ext4 · snapshots → Btrfs/ZFS · NAS → ZFS · Windows → NTFS · Mac → APFS · shared USB stick → exFAT · EFI partition → FAT32.