Tech Digest

Guide

Storage layout: ZFS, btrfs, mdadm, or just one disk

Redundancy protects you from a disk dying. It does nothing about deletion, ransomware, a bad upgrade or the house burning down. Decide the backup first, then pick the layout.

Last reviewed

Should you use ZFS, btrfs, mdadm or a single disk for a home server?

Use a single disk plus a tested off-site backup if you are starting out; it beats a mirror with no backup every time. Use a ZFS mirror when you have two matched disks and 8 GB of RAM to spare, because checksums plus snapshots plus send/receive is the strongest combination available. Use btrfs when you want snapshots and the ability to add odd-sized disks later, and never use its raid5 or raid6 modes, which the project still classifies as unstable. Use SnapRAID with MergerFS for a large media archive where per-file recovery and independent disks matter more than speed.

Start here, because it reorders everything else: RAID is not a backup, and for a lot of home servers a single disk plus a real backup is a better system than a mirror plus no backup.

Redundancy protects against exactly one event, a disk dying. It does not protect against rm -rf on the wrong path, against ransomware, against a filesystem bug, against a bad upgrade writing a corrupt database, against the machine being stolen, or against a fire. All of those replicate to the mirror at wire speed. And in practice those causes account for far more lost home server data than mechanical failure does.

So the order is: decide the backup, then decide the layout. If your budget buys either a second disk or a year of off-site storage, buy the off-site storage. Backups that actually restore covers the restore side and Backup planner sizes it.

Once you have that, redundancy is genuinely worth having, because it converts "restore 4 TB over a domestic uplink for three days" into "replace a disk". That is the actual value proposition, and it is about uptime, not safety.

ZFS#

What it gives you. End-to-end checksums on every block, which means it detects and, with redundancy, repairs silent corruption rather than serving you bad data. Snapshots that cost nothing to take. zfs send | zfs receive, which is the single best replication tool available to a self-hoster: incremental, block-level, and it moves a 2 TB dataset to another machine without walking the filesystem. Transparent compression, which is usually a net performance win. Variable-width stripes, which structurally eliminate the write hole.

What it costs you.

RAM appetite is real but overstated. Proxmox's guidance is start at 8 GB and add about 1 GB per TB of pool. The famous "1 GB per TB" rule originated in deduplication sizing and does not apply unless you enable dedup, which you should not. Watch the ARC default: Proxmox installs from the 8.1 ISO onward write a zfs_arc_max targeting 10 percent of RAM capped at 16 GiB, while upstream ZFS defaults to half of system memory. On a 64 GB host that is a 32 GB difference in what is left for containers, and it presents as processes being killed for memory.

Growth does not work the way people expect, though it is better than it was. OpenZFS 2.3.0 (January 2025) added RAIDZ expansion, so you can add one disk at a time to an existing raidz vdev. The caveats matter: existing data keeps its original parity ratio until rewritten, so the capacity gain is not immediate; you cannot change the RAIDZ level; and you still cannot remove a raidz vdev. If you want to grow a disk at a time and change your mind later, use mirrored pairs, not raidz.

Consumer SSD wear is the trap nobody mentions until the drive is at 80 percent. ZFS metadata plus small synchronous writes plus, on Proxmox VE, the pmxcfs cluster database, produce a constant stream of small writes. On a DRAM-less consumer QLC drive the wearout indicator can climb several percent a month. Check the Wearout column in the Proxmox disk view, and use drives with power loss protection for anything holding VMs or databases.

btrfs#

What it gives you. Checksums and snapshots like ZFS, plus something ZFS does not have: genuinely flexible growth. You can add and remove devices of different sizes online and rebalance, which suits a home server that grows by one leftover disk at a time. It is in mainline Linux, so there is no out-of-tree module to break on a kernel upgrade, and it is the default root filesystem on several distributions.

What it costs you. The parity modes. The official btrfs status page still lists RAID56 as unstable, states that the block group is not implemented and the on-disk format is not finalized, and keeps it behind an experimental build flag. Scrub combined with RAID56 is rated only mostly OK. raid1 and raid10 are rated OK and are fine to run. Treat raid5 and raid6 as not existing.

Also note that btrfs raid1 means "two copies of every block", not "two disks", so a raid1 profile across three odd-sized disks gives you roughly half the total capacity and tolerates one failure. That is a feature; it is just not what the name implies.

mdadm plus ext4 or XFS#

What it gives you. Boring, and boring is a feature. Every Linux administrator alive understands it, every distribution installer offers it, every recovery live-USB has the tools, and there are twenty years of answers to any question you can ask. Performance is predictable and it has no RAM appetite worth discussing.

What it costs you. No checksums. mdadm cannot tell you which copy is correct, only that the two disagree, which it discovers during a check pass and reports as a mismatch count. Silent corruption is passed through to your application.

And the write hole is a real thing here, documented in the md man page: interrupting a write to a RAID456 array can leave data and parity inconsistent, and a later rebuild reconstructs the wrong data. There are two supported mitigations. A dedicated journal device persists data and parity before writing to the array. PPL, the partial parity log, stores partial parity in the member drives' own metadata and needs no extra disk, at some write cost. Separately, a write-intent bitmap records which regions may be out of sync, which makes resync after an unclean shutdown fast rather than a full rebuild.

sh
# consistency policy and bitmap, on an existing array
sudo mdadm --detail /dev/md0 | grep -i -E 'consistency|bitmap'
# monthly scrub
echo check | sudo tee /sys/block/md0/md/sync_action
cat /sys/block/md0/md/mismatch_cnt

SnapRAID plus MergerFS#

What it gives you. For a large, mostly static media archive this is the layout that beats everything else, and it is under-recommended because it is unfashionable.

Disks are independent filesystems with whole files on them. MergerFS unions them into one namespace so /mnt/media looks like one big directory. SnapRAID computes parity across them on a schedule, up to six parity levels, well past what RAID6 offers. Lose more disks than you have parity for and you lose data only on the failed disks; every other disk still mounts and reads normally. That per-file survivability is the whole point.

The secondary benefits are large. Disks spin down independently, so watching one film wakes one disk instead of six, which is a genuine line on the electricity bill (see What a home server costs to run). You can mix any capacities. You can add a disk whenever you like. SnapRAID hashes everything, so it detects silent corruption that mdadm would not.

What it costs you. It is not real-time. The FAQ is explicit that SnapRAID is closer to a partial backup than to RAID: it requires periodic snapraid sync, and files added or changed since the last sync on a failed disk are gone. There is no striping, so a single file reads at one disk's speed. It is entirely wrong for VM images, databases or anything changing continuously.

Unraid sells a commercial version of the same idea with a real-time parity array and a UI, at 49 to 249 USD depending on device count, which is a reasonable thing to pay for if you would rather not schedule cron jobs.

The scrub, and why the rebuild is the dangerous part#

A scrub reads every allocated block and verifies it. It is the only mechanism that finds latent corruption while you still have redundancy to repair it from. Monthly is right for a home pool; weekly is wear and keeps disks awake for no benefit.

LayoutScrub command
ZFSzpool scrub tank
btrfsbtrfs scrub start /mnt/data
mdadmecho check > /sys/block/md0/md/sync_action
SnapRAIDsnapraid scrub -p 8

Rebuilds are where arrays actually die. Replacing a 20 TB disk means reading every allocated sector of every surviving disk under sustained load for a day or more, on disks that are the same age, from the same batch, and have led the same life. Backblaze's Q1 2026 Drive Stats put the fleet annualized failure rate at 1.24 percent across 341,263 drives, which is low until you concentrate your exposure into one long high-stress window with no redundancy left.

The practical rule: above roughly 8 TB per disk, single parity is not enough. Use raidz2, RAID6 or mirrored pairs. Mirrors resilver fastest because they copy one disk rather than reading all of them, which is why they remain popular for anything performance-sensitive despite the capacity cost. And run SMART monitoring, with Scrutiny or plain smartd, so you replace a failing disk before it is the second one.

The dataset layout decides how easy your upgrades are#

This is the part that gets skipped and then hurts every month for years. Whether you can snapshot before an upgrade and roll back in ten seconds is determined by whether you split datasets per service when you created the pool.

Do this:

sh
zfs create -o compression=lz4 tank/apps
zfs create tank/apps/immich
zfs create tank/apps/paperless
zfs create -o recordsize=1M tank/media

Then a risky upgrade becomes:

sh
zfs snapshot tank/apps/immich@pre-v3
docker compose pull && docker compose up -d
# if it goes wrong
docker compose down
zfs rollback tank/apps/immich@pre-v3

If instead everything lives in one dataset, rolling back Immich also rolls back Jellyfin's watch history and three days of documents, so you will not do it, so you will not take the snapshot, so you will upgrade blind.

Set atime=off on datasets you want to leave alone, use recordsize=1M for bulk media and 16K to 64K for database datasets, and keep container data on SSD so the spinning pool can actually sleep.

One recommendation per situation#

  • First server, one machine, under 4 TB. One disk, ext4 or btrfs single, plus restic or Kopia to off-site storage on a schedule you have tested. Do not buy a second disk yet.
  • Two matched disks, 16 GB RAM or more. ZFS mirror. Checksums, snapshots and zfs send for the price of one extra disk. This is the sweet spot for most home servers.
  • Two odd-sized disks, or a machine short on RAM. btrfs raid1. Same protection class, no ARC, and you can swap in a bigger disk later without rebuilding the world.
  • Four to eight matched disks, mixed workload with VMs. ZFS raidz2, or mirrored pairs if you value resilver speed and easy expansion over capacity. Run Proxmox VE or TrueNAS Community Edition and let it manage the pool.
  • A big media archive of mismatched disks. SnapRAID plus MergerFS, or Unraid if you prefer to pay for the UI. Per-file survivability and independent spin-down beat striping for this workload.
  • You genuinely do not want to think about it. TrueNAS Community Edition with a mirror, scheduled scrubs and scheduled replication. Proxmox vs TrueNAS and Unraid vs TrueNAS cover that decision.
  • Whatever you pick. Monthly scrub, SMART alerting that reaches your phone, one off-site copy, and one restore you have actually performed.

What to do next#

Create the datasets before you copy data in, because the split is painful to retrofit and it is what makes snapshot-before-upgrade a habit rather than an intention. Then size the off-site pile with Backup planner, set the scrub and SMART schedule the same day, and read An update strategy that does not lose data so the snapshots you are now able to take are actually taken.

Questions#

Is RAID a backup?

No, and the distinction is not pedantic. RAID protects against one specific failure: a disk dying. It replicates a deletion instantly, replicates a ransomware encryption instantly, replicates a bad upgrade's corrupted database instantly, and burns with the house. Every survey of data loss in home labs finds the same causes at the top, and disk failure is not the first of them. Build the backup first: see Backups that actually restore.

How much RAM does ZFS need?

Less than the folklore says, more than a mini PC has spare. Proxmox's own guidance is to start at 8 GB and add roughly 1 GB per TB of pool. The commonly quoted 1 GB per TB rule came from deduplication guidance and does not apply if you leave dedup off, which you should. Note that Proxmox installs since 8.1 cap the ARC at 10 percent of RAM with a 16 GiB ceiling, while upstream ZFS defaults to half of system memory, which is a large difference on an upgraded host.

Can you add a single disk to a ZFS pool?

Since OpenZFS 2.3.0 (January 2025) you can expand a RAIDZ vdev one disk at a time, which removes the oldest complaint about ZFS. It is not the same as what people expect: existing data keeps its original parity-to-data ratio until it is rewritten, so you do not immediately get the full capacity gain, you still cannot change the RAIDZ level, and you still cannot remove a RAIDZ vdev from a pool. Mirrors remain the flexible option.

Is btrfs RAID5 safe yet?

No. The official btrfs status page still lists RAID56 as unstable, notes the block group is not implemented and the on-disk format is not finalized, and keeps it behind an experimental build option. Scrub combined with RAID56 is rated only mostly OK. btrfs raid1 and raid10 are rated OK and are perfectly usable; the parity modes are not.

What is the RAID5 write hole?

If power is lost partway through a stripe update, the data blocks and the parity block can end up inconsistent, and a later rebuild will then reconstruct wrong data with no error. Linux md documents two mitigations: a dedicated journal device that persists data and parity before writing, and PPL (partial parity log), which stores partial parity in the member drives' own metadata and needs no extra disk. ZFS avoids the problem structurally with variable-width stripes.

How often should I scrub?

Monthly is right for a home pool. A scrub reads every allocated block and verifies it against its checksum, which is the only way you find silent corruption before a rebuild needs that block. On ZFS it is zpool scrub tank, on btrfs btrfs scrub start /mnt/data, on mdadm echo check > /sys/block/md0/md/sync_action, and on SnapRAID snapraid scrub. Weekly is unnecessary wear and keeps disks awake, which costs real money.

Is a rebuild dangerous on large drives?

It is the highest-risk period the array ever has. Replacing a 20 TB drive means reading every allocated sector of every surviving disk for a day or more, under sustained load, on drives that are the same age and from the same batch. Backblaze reported a 1.24 percent annualized failure rate across 341,263 drives in Q1 2026, which is small until you concentrate the exposure into one long window. Above roughly 8 TB per disk, use two-parity layouts or mirrors, not single parity.

Sources#

Published . Last reviewed . Found something out of date? Tell us and we will fix it and log the change.