duf is a df replacement that prints your mounted filesystems as grouped, color-coded tables instead of df's raw whitespace columns. Run duf with no arguments and it shows you local disks, network mounts, and special filesystems in separate boxes, each with a usage bar and percentages already worked out. It is one statically-linked Go binary, so there is nothing to configure and nothing to learn beyond a handful of filter flags.
The reason to reach for it: df -h dumps every loop device, every tmpfs, and every snap mount into one undifferentiated list, and you end up squinting to find the one disk that is actually filling up. duf groups those by type and colors the nearly-full ones, so the disk you care about jumps out. Everything below is install, filtering, sorting, and the --json output that makes it scriptable.
Install duf
duf is packaged on most distributions now, so you rarely need to grab a binary by hand.
# Debian 12+ / Ubuntu 22.04+
sudo apt install duf
# Fedora
sudo dnf install duf
# Arch
sudo pacman -S duf
# macOS
brew install dufIt ships in the Debian and Ubuntu repos from the versions above; on an older release you install the .deb from the GitHub releases page instead. There is no daemon, no config file, and no root requirement for reading mount info. Once installed, just run it.
The default output
duf╭───────────────────────────────────────────────────────────────────────────╮
│ 2 local devices │
├──────────────┬────────┬────────┬───────┬───────────────────────────┬───────┤
│ MOUNTED ON │ SIZE │ USED │ AVAIL │ USE% │ TYPE │
├──────────────┼────────┼────────┼───────┼───────────────────────────┼───────┤
│ / │ 117.0G │ 78.4G │ 32.6G │ [######............] 67.0% │ ext4 │
│ /boot │ 1.0G │ 213.0M │ 787.0M│ [####..............] 20.8% │ ext4 │
╰──────────────┴────────┴────────┴───────┴───────────────────────────┴───────╯
Each group is its own table with a heading like 2 local devices. The USE% column is a literal bar, and on a real terminal it is colored: green well under, amber as it climbs, red when a disk is nearly full. That coloring is the single biggest reason duf beats reading df columns; you do not have to compare numbers by eye to spot the problem.
Filter to the devices you care about
By default duf groups filesystems into local, network, fuse, special, loops, and binds. On a developer laptop the special and loops groups are noise, so scope the output to what matters.
# only the real, physical disks
duf --only local
# only local plus network mounts, skip everything else
duf --only local,network--only takes a comma-separated list of those group names and shows nothing else. Its inverse is --hide:
# everything except the loop devices and special filesystems
duf --hide loops,specialYou can also filter by filesystem type or by mount point directly:
# only tmpfs and vfat filesystems
duf --only-fs tmpfs,vfat
# only the root and home mount points
duf --only-mp /,/home
# hide a noisy mount point (wildcards work)
duf --hide-mp '/snap/*'--only-mp and --hide-mp support glob wildcards like /sys/*, which is the clean way to drop a whole tree of pseudo-mounts. The opposite of scoping down is --all, which adds the pseudo, duplicate, and inaccessible filesystems that duf hides by default. I reach for --all maybe once a year, when I am chasing a bind mount that is not showing up.
Sort and pick columns
duf sorts by mount point by default. The flag I use constantly is --sort usage, which floats the fullest disk to the top.
duf --sort usage--sort accepts mountpoint, size, used, avail, usage, type, filesystem, and the inode variants. If you only want certain columns, --output takes the same kind of list:
duf --output mountpoint,size,used,avail,usageFor inode exhaustion (the classic "disk has free space but writes fail" case), --inodes swaps the block columns for inode counts. That one has saved me more than once on a box that was out of inodes from millions of tiny session files while df -h still showed gigabytes free.
Pipe duf into scripts with --json
duf is for humans, but --json makes it scriptable too.
duf --json | jq '.[] | select(.mount_point=="/") | .used'84198547456
The JSON is an array of objects, one per filesystem, with named fields like mount_point, total, used, free, inodes, device, fs_type, and type. (Note the field names are total/free, not the SIZE/AVAIL column headers from the table, and there is no precomputed usage field in the JSON, so you derive the percentage yourself from used / total.) That is cleaner to parse than scraping df columns with awk, because you get raw bytes and named fields instead of pre-formatted human strings you have to un-format. For a monitoring check, duf --json --only local | jq is a tidy one-liner. When duf's output is not a terminal (a pipe, a redirect to a file, a cron job), it drops the colors and the box-drawing on its own, so you do not need a --no-color flag; reach for --json when you want structure and let the plain table fall out automatically when you do not.
duf vs df vs ncdu
These three get confused. They solve different problems.
| Tool | What it answers | Reads | Best for |
|---|---|---|---|
df | How full is each mounted filesystem | Mount table | Universal, always present, scriptable |
duf | Same, but readable and grouped | Mount table | Quick eyeball check of which disk is full |
ncdu | Which directories are eating the space | Walks the tree | Hunting down what to delete |
duf and df answer the same question (per-filesystem usage) and read the same kernel mount data, so they are interchangeable for the "is the disk full" check. duf just renders it better. ncdu is a different job entirely: it walks a directory tree to tell you which folders are big, which is what you run after duf tells you / is at 95%. If you are tracking down the actual files, see how to find the largest files on disk.
When to stick with df
duf is the nicer daily driver, but it is not always the right call.
- Scripts that must run anywhere.
dfis in every POSIX environment with zero install. A shell script you ship to servers you do not control should usedf(orduf --jsononly where you can guarantee the binary is present). - A genuinely minimal container or recovery shell. If you are in a busybox initramfs or a scratch image,
dfis there anddufis not. Do not add a dependency for a one-off check. - Muscle memory in a hurry. During an incident,
df -his the thing your fingers already know.dufis worth installing on machines you live in, not memorizing under pressure.
For everything else (your workstation, dev boxes, anywhere you read disk usage by eye more than once a week), duf earns its place. Pair it with a modern ls replacement like exa/eza for richer directory listings and the whole "where did my space go" loop gets faster.
One install gotcha worth knowing: oh-my-zsh's common-aliases plugin defines duf='du -sh *', which shadows the binary if you have that plugin enabled. Run unalias duf (and drop it in your .zshrc after the oh-my-zsh load line) so the real command wins.
See also
- exa / eza, a modern ls replacement: the same "friendlier rewrite of a core Unix tool" idea applied to directory listings, with colors, git status, and tree mode
- Find the largest files on disk: once
dufshows a disk is nearly full, this is how you track down the actual files eating the space - External: duf on GitHub, the project README and full flag reference.
FAQ
Sources
Authoritative references this article was fact-checked against.





