First of all make sure contrib is enabled in /etct/apt/sources.list, if not follow this guide to add "non-free contrib" to the repos.
ZFS is popular because it provides actual error checking and correction to a level that is better than most RAID arrays. The other benefit of ZFS is that in inherently acts like a ramdisk and at a minimum caches directories and file structures, so you save a lot of wear and tear on your storage. Even better, the more RAM you have the better it works, it is not uncommon for a busy server/array to use 60-90GB of RAM at a minimum and ZFS generally will not overallocate or interfere with other services.
apt install zfsutils-linux
Let's see the main binaries that come with zfs:
dpkg -L zfsutils-linux|grep bin
/sbin
/sbin/fsck.zfs
/sbin/mount.zfs
/sbin/zdb
/sbin/zfs
/sbin/zfs_ids_to_path
/sbin/zgenhostid
/sbin/zhack
/sbin/zpool
/sbin/zstream
/sbin/zstreamdump
/sbin/zvol_wait
/usr/sbin
/usr/sbin/arc_summary
/usr/sbin/arcstat
/usr/sbin/dbufstat
In most cases you will spend most of your time using the "zfs", and "zpool" commands in my experience.
ZFS is a block device tool, so you will need extra drives that are empty or are OK to empty. Be 100% sure of the drives you need to use and that they don't have important data before proceeding.
In this case here is an example of 8 drives all of the same size.
/dev/sda
/dev/sdb
/dev/sdc
/dev/sdd
/dev/sde
/dev/sdf
/dev/sdg
/dev/sdh
Normally in typical RAID thinking some popular ways might be RAID 0 for maximum performance and storage capacity but that is normally bad since data loss is guaranteed with the failure of even one drive.
Another way could be RAID 1 which give good performance and faster read speeds but you would lose half of your capacity (eg. 4 drives total space since the other 4 are essentially mirrors).
Another way could have been RAID10 which is a decent blend of performance and redundancy but you still lose 4 drives worth of capacity. Essentially this is 2 arrays of RAID 1 stripped into a RAID 0.
With RAID 5 you would lose only 1 disk's capacity but have performance issues, plus it takes forever to build or rebuild arrays that are larger like this due to the parity calculations.
So what are some similar options in ZFS?
ZFS's advantage is that it has more flexibility compared to tradtional RAID where disks must be of the same size. It makes upgrading the array and increasing the size very difficult, whereas ZFS can handle this fairly well in most cases.
Let's talk about the main modes of ZFS
mirror: Basically this is just like RAID 1 but you have the benefit of no bitrot concerns and huge redundancy, plus the easier path of upgrading your space in the future.
The number in the name is the amount of disks you can lose before having dataloss, eg. RAIDZ1 means 1 disk can fail, Z2 means 2, and 3 means 3 can fail.
RAIDZ1: 87.5% capacity
RAIDZ2: 75.0% capacity
RAIDZ3: 62.5% capacity
As we can see, we are mainly trading a combination of disk capacity for efficiency and in generally most cases you are more efficient and redundant compared to RAID, with the benefit of easier upgrade paths if you want to upgrade your disks and array.
In my example we'll use the 8 disks in a RAIDZ2 configuration, giving us a decent performance and redundancy. Of course you would adjust this to the level of fault tolerance you need.
Before we do that we should be familar with the main zpool commands:
usage: zpool command args ...
where 'command' is one of the following:
version
create [-fnd] [-o property=value] ...
[-O file-system-property=value] ...
[-m mountpoint] [-R root]
destroy [-f]
add [-fgLnP] [-o property=value]
remove [-npsw]
labelclear [-f]
checkpoint [-d [-w]]
list [-gHLpPv] [-o property[,...]] [-T d|u] [pool] ...
[interval [count]]
iostat [[[-c [script1,script2,...][-lq]]|[-rw]] [-T d | u] [-ghHLpPvy]
[[pool ...]|[pool vdev ...]|[vdev ...]] [[-n] interval [count]]
status [-c [script1,script2,...]] [-igLpPstvxD] [-T d|u] [pool] ...
[interval [count]]
online [-e]
offline [-f] [-t]
clear [-nF]
reopen [-n]
attach [-fsw] [-o property=value]
detach
replace [-fsw] [-o property=value]
split [-gLnPl] [-R altroot] [-o mntopts]
[-o property=value]
initialize [-c | -s] [-w]
resilver
scrub [-s | -p] [-w]
trim [-dw] [-r
import [-d dir] [-D]
import [-o mntopts] [-o property=value] ...
[-d dir | -c cachefile] [-D] [-l] [-f] [-m] [-N] [-R root] [-F [-n]] -a
import [-o mntopts] [-o property=value] ...
[-d dir | -c cachefile] [-D] [-l] [-f] [-m] [-N] [-R root] [-F [-n]]
[--rewind-to-checkpoint]
export [-af]
upgrade
upgrade -v
upgrade [-V version] <-a | pool ...>
reguid
history [-il] [
events [-vHf [pool] | -c]
get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]>
set
zpool create -f ourmirror raidz2 /dev/sdc /dev/sdd /dev/sde /dev/sdf /dev/sdg /dev/sdh /dev/sdi /dev/sdj
The above created a ZFS pool called "ourmirror" with the raidz2 format and used the devices /dev/sdc /dev/sdd /dev/sde /dev/sdf /dev/sdg /dev/sdh /dev/sdi /dev/sdj
We can now check the status:
zpool status
pool: ourmirror
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
ourmirror ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
sdg ONLINE 0 0 0
sdh ONLINE 0 0 0
sdi ONLINE 0 0 0
sdj ONLINE 0 0 0
errors: No known data errors
zpool iostat 1
This will show the iostats of all pools every 1 second.
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
ourmirror 4.73T 124.4T 179 238 8.88M 35.1M
You can't accurately check memory usage in top, but if you find yourself wondering why your system uses so much RAM that appears to be unaccounted for you will want to use "arc_summary".
arc_summary
We just took a snippet of the top output which basically tells you overall RAM usage.
ZFS Subsystem Report Tue Jun 02 19:04:43 2026
Linux
Machine: server (x86_64) 2.0.3-9+deb11u1
ARC status: HEALTHY
Memory throttle count: 0
ARC size (current): 64.8 % 61.2 GiB
Target size (adaptive): 64.9 % 61.2 GiB
Min size (hard limit): 6.2 % 5.9 GiB
Max size (high water): 16:1 94.3 GiB
Most Frequently Used (MFU) cache size: 72.1 % 36.7 GiB
Most Recently Used (MRU) cache size: 27.9 % 14.2 GiB
Metadata cache size (hard limit): 75.0 % 70.7 GiB
Metadata cache size (current): 21.5 % 15.2 GiB
Dnode cache size (hard limit): 10.0 % 7.1 GiB
Dnode cache size (current): 78.0 % 5.5 GiB
install, zfs, linux, ubuntu, debian, mintfirst, contrib, enabled, etct, apt, sources, quot, repos, https, realtechtalk, how_to_add_contrib_packages_to_debianlinuxmint_by_editing_etcaptsourceslist, articles, zfsutils, binaries, dpkg, grep, bin, sbin, fsck, mount, zdb, zfs_ids_to_path, zgenhostid, zhack, zpool, zstream, zstreamdump, zvol_wait, usr, arc_summary, arcstat, dbufstat, commands, volume, ok, proceeding, dev, sda, sdb, sdc, sdd, sde, sdf, sdg, sdh, raid, maximum, capacity, guaranteed, speeds, eg, essentially, mirrors, blend, redundancy, arrays, stripped, disk, rebuild, larger, parity, calculations, flexibility, tradtional, disks, upgrading, array, increasing, whereas, modes, bitrot, dataloss, raidz, z, mainly, trading, efficiency, generally, efficient, redundant, upgrade, paths, ll, configuration, adjust, tolerance, familar, usage, args, fnd, mountpoint, vdev, fglnp, npsw, labelclear, checkpoint, ghlppv, interval, iostat, lq, rw, ghhlppvy, iglppstvxd, online, offline, nf, reopen, attach, fsw, detach, glnpl, altroot, mntopts, newpool, initialize, resilver, scrub, trim, dw, import, dir, cachefile, rewind, export, af, reguid, il, vhf, hp, sync,