Disk-full alerts are easier to handle when you can separate filesystem capacity from directory growth. The df command in Linux reports used space, available space, mount points, filesystem types, and inode usage for mounted filesystems, making it the first check before you start deleting files or expanding storage.
The examples assume GNU df, the implementation shipped with GNU coreutils on mainstream Linux distributions such as Ubuntu, Fedora, Rocky Linux, and Debian. Use the local man df page or the GNU Coreutils df manual when you need the complete option reference for your installed version.
Understand the df Command Output
df reads mounted filesystem statistics. With no path argument, it lists mounted filesystems. With a file or directory argument, it reports the filesystem that contains that path.
Basic df Syntax
df [OPTIONS] [FILE_OR_DIRECTORY...]
Check the root filesystem with human-readable units when the alert names the whole system disk rather than an application path:
df -h /
Example output from an ext4 root filesystem:
Filesystem Size Used Avail Use% Mounted on /dev/sda2 118G 11G 102G 10% /
The -h option prints human-readable units using powers of 1024, so values appear as K, M, G, or larger units instead of raw 1K blocks.
Verify df Is Available
Normal Linux systems include df through coreutils. Confirm the executable and implementation before using GNU-specific options such as --output:
command -v df
df --version | head -n 1
Example output shows the command path and GNU coreutils version:
/usr/bin/df df (GNU coreutils) 9.7
Read df Output Columns
| Column | Meaning | Reader Check |
|---|---|---|
Filesystem | Device, pseudo-filesystem, network share, or another source mounted at a path. | Use it to identify which device or source backs the mount. |
Size | Total filesystem capacity in the selected unit. | Check whether the filesystem is smaller than expected. |
Used | Allocated space already consumed. | Compare with Avail before cleanup or expansion. |
Avail | Space available to normal writes after filesystem accounting and reserves. | Treat this as the practical free-space value. |
Use% | Percentage of the filesystem currently used. | Use it for quick alert thresholds. |
Mounted on | Directory where the filesystem is attached. | Match the full filesystem to the path you are investigating. |
df Command Quick Reference
| Task | Command Pattern | What It Shows |
|---|---|---|
| Show all mounted filesystems | df -h | Readable space totals for every visible mount. |
| Check one path | df -h /var | The filesystem that contains /var. |
| Check the current directory | df -hT . | Filesystem type and capacity for your current working directory. |
| Check several paths | df -hT / /home /var /tmp | Shows whether common paths share one filesystem or use separate mounts. |
| Show filesystem type | df -Th / | Type column, such as ext4, xfs, or btrfs. |
| Check inode usage | df -ih / | Inode totals and inode percentage where the filesystem reports them. |
| Exclude temporary filesystems | df -h -x tmpfs -x devtmpfs | Cleaner output without common memory-backed pseudo-filesystems. |
| Hide loop and squashfs rows | df -h -x tmpfs -x devtmpfs -x squashfs | Removes common temporary mounts plus read-only app image mounts. |
| Use a custom column set | df -h --output=source,fstype,size,used,avail,pcent,target / | Selected columns in a predictable order. |
| Sort by use percentage | df -h --output=source,pcent,target | tail -n +2 | sort -k2 -hr | Highest reported filesystem percentages first. |
| Use POSIX-style output | df -P / | One-line-per-filesystem format for portable scripts. |
Check Filesystem Space with df
Start with the smallest question that answers the alert or task. A full df -h report is useful for a quick overview, while a path-specific check avoids guessing which mount owns a directory.
Show All Mounted Filesystems
df -h
This report can include disk partitions, temporary filesystems, removable media, network mounts, and user runtime mounts. The exact list depends on what is mounted when you run the command.
Check the Root Filesystem
Use / when you need the root filesystem that stores core system directories such as /etc, /usr, and usually /var unless those paths are separate mounts:
df -h /
Filesystem Size Used Avail Use% Mounted on /dev/sda2 118G 11G 102G 10% /
Check the Filesystem for a Specific Directory
Pass a directory or file path to find the filesystem that contains it. This is safer than assuming /var, /home, or an application directory lives on the same filesystem as /:
df -h "$HOME"
On systems where /home is separate, the mount point in the final column changes accordingly. On systems where home directories share the root filesystem, the mount point remains /.
Check the Current Directory or a File Path
df accepts a relative path, an absolute directory, or a file. Use . when you want the filesystem for the directory your shell is already using:
df -hT .
A file path answers the same question for the filesystem that stores that file. This is useful when a config file, database file, or log path is the object you are investigating:
df -hT /etc/passwd
The final column still shows the mounted filesystem target, not necessarily the exact path you typed. That distinction matters when a directory is only one path inside a larger mounted filesystem.
Check Several Common Mount Points Together
Check several common paths in one command when you do not yet know whether the system separates /home, /var, or /tmp from the root filesystem:
df -hT / /home /var /tmp
Example output where /, /home, and /var share one ext4 filesystem while /tmp is memory-backed:
Filesystem Type Size Used Avail Use% Mounted on /dev/sda2 ext4 118G 11G 102G 10% / /dev/sda2 ext4 118G 11G 102G 10% / /dev/sda2 ext4 118G 11G 102G 10% / tmpfs tmpfs 1.7G 8.0K 1.7G 1% /tmp
Repeated device and mount rows mean those path arguments live on the same filesystem. A separate source or mount target means that path can fill independently.
Show Filesystem Types with df -T
Add -T when the filesystem type affects the next decision, such as checking whether the root filesystem is ext4, XFS, or Btrfs:
df -Th /
Example output from a Btrfs root filesystem:
Filesystem Type Size Used Avail Use% Mounted on /dev/nvme0n1p3 btrfs 118G 6.8G 110G 6% /
Compare Binary and Decimal Units
-h uses powers of 1024, while -H and --si use powers of 1000. Decimal units often look larger because storage vendors usually advertise drive capacity with powers of 1000:
df -h /
df -H /
df --si /
For fixed reporting units, use -B. Whole-unit forms such as -BG and -BM keep the unit in the header and are often easier to compare in reports. Print GiB-sized rows with -BG:
df -BG /
Filesystem 1G-blocks Used Available Use% Mounted on /dev/sda2 118G 11G 102G 10% /
Filter df Output for Cleaner Reports
Unfiltered df output can be noisy on desktop systems, containers, and hosts with many temporary mounts. Filter by filesystem type or locality when you need a report that focuses on persistent storage.
Exclude tmpfs and devtmpfs Entries
Temporary memory-backed filesystems such as tmpfs and devtmpfs are often not the storage you are trying to free. Exclude them with repeated -x options:
df -h -x tmpfs -x devtmpfs
Keep the filters explicit. A desktop system can still show optical media, separate boot partitions, Btrfs subvolumes, or mounted data disks after temporary filesystems are removed.
Hide Loop and Read-Only Mount Noise
Ubuntu desktops and some application-packaging setups can show many /dev/loop* rows backed by read-only squashfs images. Those rows usually represent mounted app images rather than writable disk space you can clean directly:
df -h -x tmpfs -x devtmpfs -x squashfs
Use this as a readability filter, not as proof those packages are unimportant. If a loop-backed application package is the actual maintenance target, manage it through its package tool instead of deleting mount paths by hand.
Limit df to Local Filesystems
The -l option limits the listing to local filesystems and omits remote mounts such as NFS when the implementation can identify them:
df -h -l
Use this when network storage would distract from local disk checks. It does not remove all pseudo-filesystems, so combine it with -x filters when you also need to hide temporary mounts.
Sort df Output by Use Percentage
Sort a focused df report when you want the fullest persistent filesystems first. The custom columns keep Use% in a known field, tail -n +2 removes the header, and sort -k6 -hr sorts that percentage from high to low:
df -h --output=source,fstype,size,used,avail,pcent,target -x tmpfs -x devtmpfs -x squashfs | tail -n +2 | sort -k6 -hr
This is an interactive report, not a cleanup command. After identifying a full filesystem, check the owning mount and then use path-level tools before removing data.
Show Only One Filesystem Type
Use -t to include only a matching filesystem type. For example, show an ext4 root filesystem only when the target path is actually on ext4:
df -h -t ext4 /
Filesystem Size Used Avail Use% Mounted on /dev/sda2 118G 11G 102G 10% /
If the path uses another filesystem type, df exits with no matching filesystems instead of printing a near match. Check the type first with df -Th / when you are unsure.
Customize df Columns with --output
GNU df can print a specific field list with --output. This keeps reports focused and avoids parsing columns you do not need:
df -h --output=source,fstype,size,used,avail,pcent,target /
Filesystem Type Size Used Avail Use% Mounted on /dev/sda2 ext4 118G 11G 102G 10% /
Common field names include source, fstype, size, used, avail, pcent, and target. Inode fields such as itotal, iused, iavail, and ipcent are also available, but --output is mutually exclusive with -i, -P, and -T on GNU df.
Check Inode Usage with df
A filesystem can run out of inodes before it runs out of block space, especially when millions of tiny files accumulate. The -i option switches df from block usage to inode usage:
df -ih /
Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sda2 7.5M 210K 7.3M 3% /
High IUse% with available block space usually points to many small files, such as cache entries, mail queue files, build artifacts, or application sessions. Clean the owning application path rather than deleting random directories from the filesystem root.
Check Inodes for Common Write Paths
Check inode usage against the paths that applications commonly write to instead of only checking /. This helps separate a full root filesystem from a separate /var, /tmp, or home filesystem:
df -ih /var /tmp "$HOME"
If one path reports high IUse%, investigate the application or service that owns that path. Millions of small cache, session, queue, or build files can block new file creation even when df -h still shows available block space.
Interpret Btrfs Inode Output
Some filesystems do not expose traditional fixed inode accounting. On Btrfs, df -ih / can show zero inode counts and - for IUse%:
df -ih /
Filesystem Inodes IUsed IFree IUse% Mounted on /dev/nvme0n1p3 0 0 0 - /
That output is not the same as an empty filesystem. It means inode-style accounting is not a useful signal for that filesystem. Use the normal block-space report from df -h and filesystem-specific tooling when Btrfs allocation details matter.
Use df in Scripts and Reports
Scripts should prefer stable output over visually aligned tables. Use POSIX output when broad compatibility matters, or use GNU --output when the script runs on systems where GNU coreutils is guaranteed.
Use POSIX Output with df -P
df -P keeps each filesystem on one line and uses POSIX-style headers:
df -P /
Filesystem 1024-blocks Used Available Capacity Mounted on /dev/sda2 123265600 10925228 106032688 10% /
For a simple threshold check, parse the capacity column from POSIX output and remove the percent sign before comparing. Keep the diagnostic, branch, and message in one small shell block:
usage=$(df -P / | awk 'NR==2 {gsub(/%/, "", $5); print $5}')
if [ "$usage" -ge 90 ]; then
printf 'root filesystem is %s%% full\n' "$usage"
else
printf 'root filesystem usage is %s%%\n' "$usage"
fi
root filesystem usage is 10%
Use this pattern for local reporting, not for blindly deleting files. A full cleanup workflow still needs to identify which path is growing and which service owns it.
Use --output for Named Columns
When GNU df is available, named columns avoid positional parsing:
df --output=source,target,pcent,avail /
Filesystem Mounted on Use% Avail /dev/sda2 / 10% 106032684
The avail value remains in 1K blocks unless you add a scaling option such as -h. Keep raw units for scripts and human-readable units for interactive reports.
Show Only Available Space for a Path
When a dashboard, ticket, or quick status note only needs practical free space, print the available column and target for the path you care about:
df -h --output=avail,target /
Avail Mounted on 102G /
Use Avail rather than subtracting Used from Size. Filesystem reserves and metadata can make that subtraction differ from the space a normal process can actually use.
Be Careful with df --total
--total adds a summary line, which can help with simple local disk reports:
df -h --total -x tmpfs -x devtmpfs -x squashfs
Do not treat the total as authoritative accounting on systems with Btrfs subvolumes, bind mounts, network mounts, or several mount points backed by the same device. Confirm the mount layout before using totals for capacity planning:
findmnt -T / -no SOURCE,FSTYPE,TARGET
/dev/sda2 ext4 /
Compare df with du and findmnt
df, du, and findmnt answer different storage questions. Use df when the question is “how full is the filesystem?”, use the du command in Linux when the question is “which files or directories are using space?”, and use findmnt when the question is “what is mounted here?”
| Tool | Best Question | Common Use |
|---|---|---|
df | How much capacity remains on a mounted filesystem? | Disk-full alerts, free-space checks, inode checks, filesystem-type filtering. |
du | Which visible paths are consuming space? | Directory cleanup, log growth checks, project or cache size reports. |
findmnt | Which source and filesystem type owns this mount point? | Mount layout checks before filtering, totals, or storage changes. |
When df and du disagree, the reason is usually deleted-but-open files, reserved blocks, filesystem metadata, mount points, snapshots, or files hidden under a mounted directory. Start with df -h /path to identify the full filesystem, then use du disk usage analysis examples to drill into visible directories.
Troubleshoot Common df Problems
Most df problems come from checking the wrong path, filtering for the wrong filesystem type, or reading inode output without considering the underlying filesystem.
Output Is Cluttered by /dev/loop Rows
Many /dev/loop* rows usually mean the system has read-only app images or similar loop-mounted filesystems. They can make df -h look noisy even though they are not writable filesystems you should clean by deleting mount paths:
df -hT
If those rows use the squashfs type, filter them from routine free-space reports:
df -h -x tmpfs -x devtmpfs -x squashfs
The filtered report should omit squashfs rows while keeping real disk partitions and separate persistent mounts visible.
df Is Slow or Hangs on Network Mounts
A stale NFS, CIFS, or other remote mount can make a plain df -h slow because df has to query mounted filesystems. Limit the first check to local filesystems when you only need local disk state:
df -h -l
List common network filesystem mounts separately when remote storage is part of the problem:
findmnt -t nfs,nfs4,cifs
No output from findmnt means those common network filesystem types are not currently mounted. If df -h -l returns normally while plain df -h stalls, investigate the remote mount rather than local disk capacity.
No Such File or Directory
A missing path produces a direct error and a nonzero exit status:
df -h /no-such-path
df: /no-such-path: No such file or directory
Check the path spelling and quote paths that contain spaces:
ls -ld "$HOME/Project Files"
df -h "$HOME/Project Files"
No File Systems Processed
Filtering by the wrong filesystem type can leave df with nothing to print. On a Btrfs or XFS root filesystem, an ext4-only filter does not match the target path:
df -h -t ext4 /
df: no file systems processed
Confirm the filesystem type, then rerun the filter with the type that actually backs the path:
df -Th /
findmnt -T / -no SOURCE,FSTYPE,TARGET
Inode Percentage Shows a Dash
If df -ih shows 0 inode totals and - for IUse%, check the filesystem type before treating the result as corruption:
df -Th /
Btrfs can report inode statistics this way through df. Use block-space usage and filesystem-specific inspection instead of inode percentages for that filesystem.
No Space Left on Device with Free Blocks Available
When writes fail with No space left on device but df -h still shows available space, check inode usage on the same filesystem. A filesystem can have room for data blocks while having no file entries left:
df -h /var
df -ih /var
If IUse% is high, look for application-owned directories that create many tiny files, such as session stores, mail queues, caches, package build trees, or test artifacts. Clean or rotate through the owning application path, then retest with df -ih /var.
df and du Do Not Match
df measures allocated filesystem space, while du walks visible directory entries. They can disagree because of deleted-but-open files, filesystem reserves, metadata, snapshots, mount points, permissions, or files hidden below another mount.
Start by confirming the filesystem that owns the path:
df -hT /var
Then inspect visible directory usage on that path before deleting anything:
sudo du -xh --max-depth=1 /var 2>/dev/null | sort -h
If visible directories do not explain the df usage, continue with deleted-open files, reserved blocks, snapshots, or mount layout checks instead of forcing a directory cleanup.
df Shows Space Still Used After Deleting Files
df counts space at the filesystem level. If a process still has a deleted file open, the filesystem can remain full even though the pathname is gone. This is common with logs, temporary files, database spill files, and long-running services.
Find deleted pathnames still held by running processes. The filter removes memory-backed memfd entries so the output stays focused on path-backed files:
sudo find /proc/*/fd -lname '* (deleted)' -printf '%p -> %l\n' 2>/dev/null | grep -v ' -> /memfd:' | head
If the output points to a service-owned file, restart or reload the owning service through its normal maintenance procedure, then recheck the affected filesystem:
df -h /var
If you cannot safely identify the owner, schedule a controlled reboot instead of killing random processes. For visible file and directory growth, switch from filesystem capacity to path usage before cleanup.
Used Plus Available Does Not Equal Size
Size, Used, and Avail do not always add up like simple arithmetic. Filesystem metadata, reserved blocks, snapshots, copy-on-write allocation, and root-only reserves can make Avail smaller than Size minus Used.
For normal operational checks, treat Avail and Use% as the practical signals. Investigate filesystem-specific reserve or snapshot settings only when those values do not match the storage plan.
Conclusion
Filesystem capacity checks are now separate from path-level cleanup. Use df -h /path first to identify the mounted filesystem, add -T or -i when type or inode state changes the diagnosis, and move to du only when you need visible directory cleanup targets.


Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags currently allowed in published comments:
<code>command</code>command<strong>bold</strong><em>italic</em><a href="https://example.com">link</a><blockquote>quote</blockquote>