Skip to main content

df — Disk Free & Filesystem Usage

df (disk free) is a standard Linux command that reports block usage and inode statistics for every mounted filesystem on your system. It tells you how much space is available, how much is used, and — critically — where each filesystem is mounted. Use it to check your WordPress root partition, log volume, backup mount, and database disk in a single command, and to catch a full disk before it takes your site offline.

Overview

df reports available and used space on mounted filesystems in a single view. Use it to confirm whether your WordPress root, log partition, backups mount, or database volume is approaching capacity before you hit "No space left on device". While du helps you find which directory is consuming space, df tells you how much space is left on the underlying filesystem.

Tool Snapshot
  • Core Function: Query mounted filesystem block and inode statistics.
  • Primary Benefit: Instant, system-wide disk capacity view — bytes and inodes in one command.
  • Where to Use: Routine VPS health checks, incident response, and cron-driven monitoring.
  • Key Insight: Passing a PATH to df does not report the file's size. It reports the filesystem that contains that path.

System Check

which df # Expected: /bin/df
df --version # Recommended: GNU coreutils 8.x+

Benefits

  • Instant capacity visibility — a single command shows every mounted disk's free space.
  • Inode awarenessdf -i exposes inode exhaustion that df -h and du both miss.
  • Scriptable output — POSIX (-P) and --output modes make parsing reliable in automation.
  • Partition-level clarity — confirms whether WordPress, logs, backups, and databases live on separate mounts or share one disk.
  • Zero dependencies — part of GNU coreutils; available on every Linux VPS by default.

Best Practices

  • Default to df -h for every routine check — human-readable units prevent misreading raw blocks.
  • Always check inodes too — run df -i alongside df -h on busy WordPress sites where cache plugins generate thousands of small files.
  • Alert at 80% — set a monitoring threshold at 80% (Use%) so you have time to act before reaching 100%.
  • Exclude virtual filesystems in scripts — use -x tmpfs -x devtmpfs to keep output focused on real disks.
  • Prefer --output for dashboards — select only the columns you need instead of parsing fixed-width text.
  • Pair with du — use df -h to identify the full filesystem, then du -h --max-depth=1 inside it to find the culprit directory.
  • Use -P in cron scripts — POSIX format guarantees stable column positions across different df versions.
  • Check backup mounts before jobs rundf -h /mnt/backups confirms the target has space before a backup starts.

Tips & Strategy

When df -h looks fine but uploads still fail

Inode exhaustion is the hidden culprit. Plugins and caches that generate many small files (thumbnails, transients, session files) can consume every available inode long before bytes run out. Always run df -i in parallel with df -h during incident triage.

Build a two-command triage sequence
df -h # Step 1 — which filesystem is running out of bytes?
df -i # Step 2 — is it actually inodes?

If step 1 looks fine but step 2 shows 90%+ usage, pivot to clearing cache or session files.

Use --output to build minimal monitoring snapshots
df -h --output=target,pcent,avail

Output is narrow enough to paste into a Slack incident thread or log to a file without noise.

Subtract virtual filesystems for cleaner views

tmpfs and devtmpfs stacks can inflate the line count. Remove them:

df -h -x tmpfs -x devtmpfs
Know the units difference between -h and -H

-h uses powers of 1024 (GiB). -H uses powers of 1000 (GB). Cloud provider dashboards typically report in GB (decimal), so use -H when comparing against your provider's metrics panel.


Syntax & Options Reference

Core Syntax

df [OPTION]... [FILE]...
  • OPTION — controls display format, filtering, and output columns.
  • FILE — optional path(s). If omitted, df reports all mounted filesystems. When a path is provided, df reports the filesystem containing that path, not the path itself.

Complete Options Table

OptionLong FormDescriptionExample
-h--human-readablePrint sizes in powers of 1024 (K, M, G, T)df -h
-H--siPrint sizes in powers of 1000 (kB, MB, GB)df -H
-i--inodesShow inode usage instead of block usagedf -i
-T--print-typeShow filesystem type columndf -T
-t TYPE--type=TYPEInclude only filesystems of TYPEdf -t ext4 -h
-x TYPE--exclude-type=TYPEExclude filesystems of TYPEdf -x tmpfs -h
-a--allInclude pseudo, duplicate, and inaccessible filesystemsdf -a -h
-l--localLimit output to local filesystems onlydf -l -h
-P--portabilityPOSIX/portability output format (script-safe)df -P
--total--totalAdd a final grand-total linedf -h --total
--output[=LIST]--output=LISTSelect specific columns (see list below)df --output=source,size,pcent
--sync--syncInvoke sync before getting usage infodf --sync -h
--no-sync--no-syncDo not invoke sync before getting usage (default)df --no-sync -h
-B SIZE--block-size=SIZEScale sizes by SIZE before printingdf -BM
--direct--directUse direct stat() call for NFS mountsdf --direct

--output Column Names

When using --output, you can mix and match from the following column identifiers:

Column NameDescription
sourceDevice or source of the filesystem
fstypeFilesystem type (ext4, xfs, tmpfs…)
itotalTotal number of inodes
iusedNumber of used inodes
iavailNumber of free inodes
ipcentInode usage percentage
sizeTotal disk space
usedDisk space used
availDisk space available
pcentUsage percentage
fileThe file name argument if specified
targetMount point

Example — select all meaningful columns:

df-full-output-columns.sh
df -h --output=source,fstype,size,used,avail,pcent,target
example-output-full-columns.txt
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda1 ext4 50G 10G 40G 20% /
tmpfs tmpfs 2.0G 0 2.0G 0% /dev/shm

Understanding PATH in df

PATH TypeExampleWhat It Resolves ToWordPress/VPS Use Case
No path (default)df -hAll mounted filesystemsRoutine server health check
Absolute directorydf -h /var/www/htmlFilesystem containing that directoryCheck WordPress root partition
Relative directorycd /var/www/html && df -h .Same as absolute, from current dirWhen already inside the site
File pathdf -h /var/www/html/wp-config.phpFilesystem containing the fileConfirm free space where WP lives
Mounted backup volumedf -h /mnt/backupsReports a separate device/mountEnsure backup disk has space
Multiple pathsdf -h / /var/www/html /var/logShows each path's filesystemCompare partitions quickly
Deep nested pathdf -h /var/www/html/wp-content/uploads/2025Still maps back to the same mountCheck uploads space without leaving WP

Practical Use Cases

1. Human-readable disk usage

df-human-readable.sh
df -h
example-output-df-human-readable.txt
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 10G 40G 20% /
tmpfs 2.0G 0 2.0G 0% /dev/shm

Use case: Default routine check — easier to read than raw block numbers.


2. Check inode usage

df-inodes.sh
df -i
example-output-df-inodes.txt
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 3276800 120000 3156800 4% /

Use case: Diagnose inode exhaustion — common when caches or session handlers generate thousands of tiny files.


3. Show filesystem type

df-filesystem-type.sh
df -T -h
example-output-df-type.txt
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda1 ext4 50G 10G 40G 20% /
tmpfs tmpfs 2.0G 0 2.0G 0% /dev/shm

Use case: Confirm filesystem type before resizing a partition or applying filesystem-specific tuning.


4. Filter to ext4 partitions only

df-only-ext4.sh
df -t ext4 -h
example-output-df-only-ext4.txt
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda1 ext4 50G 10G 40G 20% /

Use case: Focus on real disk-backed partitions and ignore virtual filesystems.


5. Exclude tmpfs (and other virtual FS)

df-exclude-virtual-filesystems.sh
df -h -x tmpfs -x devtmpfs
example-output-df-exclude-virtual.txt
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 10G 40G 20% /

Use case: Keep output focused on real disks — especially useful in scripts and monitoring output.


6. Local filesystems only

df-local-filesystems-only.sh
df -h -l
example-output-df-local.txt
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 10G 40G 20% /

Use case: Suppress NFS or remote mounts so you focus on the VPS's own disk.


7. POSIX format (script-safe)

df-posix-output.sh
df -P /var/www/html
example-output-df-posix.txt
Filesystem 1024-blocks Used Available Capacity Mounted on
/dev/sda1 52403200 10485760 41917440 20% /

Use case: Safe, stable column format for parsing in shell scripts — column positions are guaranteed by the POSIX standard.


8. Grand total row

df-total.sh
df -h --total
example-output-df-total.txt
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 10G 40G 20% /
tmpfs 2.0G 0 2.0G 0% /dev/shm
total 52G 10G 42G 19%

Use case: Get an at-a-glance aggregate of all mounted disk space.


9. Custom column selection

df-custom-columns.sh
df -h --output=source,fstype,size,used,avail,pcent,target
example-output-df-custom-columns.txt
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda1 ext4 50G 10G 40G 20% /
tmpfs tmpfs 2.0G 0 2.0G 0% /dev/shm

Use case: Precise, readable reporting for dashboards and incident logs.


10. Minimal monitoring snapshot

df-monitoring-columns.sh
df -h --output=target,pcent,avail
example-output-df-monitoring-columns.txt
Mounted on Use% Avail
/ 20% 40G
/dev/shm 0% 2.0G

Use case: Narrow snapshot suitable for Slack, PagerDuty notes, or a simple monitoring script.


11. Check the partition hosting WordPress

df-check-wordpress-root.sh
df -h /var/www/html
example-output-df-wp-root.txt
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 10G 40G 20% /

Use case: Confirm which partition your WordPress site lives on and how much space remains.


12. Check backup volume before running a backup job

df-check-backup-mount.sh
df -h /mnt/backups
example-output-df-backup-mount.txt
Filesystem Size Used Avail Use% Mounted on
/dev/sdb1 200G 50G 150G 25% /mnt/backups

Use case: Verify backup storage has sufficient headroom before kicking off a large backup.


13. Monitor the logs partition

df-check-var-log.sh
df -h /var/log
example-output-df-var-log.txt
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 20G 30G 40% /

Use case: Detect log growth before it fills the disk and kills PHP-FPM or MySQL.


14. Monitor the database volume

df-check-mysql-volume.sh
df -h /var/lib/mysql
example-output-df-mysql-volume.txt
Filesystem Size Used Avail Use% Mounted on
/dev/sdb1 100G 30G 70G 30% /var/lib/mysql

Use case: Monitor database storage separately if MySQL or MariaDB is on its own mount.


15. Detect near-full disk (critical alert scenario)

df-disk-nearly-full.sh
df -h
example-output-df-nearly-full.txt
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 49G 1.0G 98% /

Use case: Trigger an immediate response — 98% usage means WordPress will fail to write uploads, logs, and sessions within minutes.


16. Detect inode exhaustion

df-inode-exhaustion-example.sh
df -i
example-output-df-inodes-full.txt
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 3276800 3276700 100 100% /

Use case: File uploads fail even though df -h shows free space. 100% IUse% is the smoking gun.


17. Include all pseudo and inaccessible filesystems

df-include-all-filesystems.sh
df -h -a
example-output-df-all.txt
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 10G 40G 20% /
tmpfs 2.0G 0 2.0G 0% /dev/shm
udev 2.0G 0 2.0G 0% /dev

Use case: Debug special or hidden mounts that do not appear in a normal df -h.


18. Custom block size output

df-block-size-mb.sh
df -BM /var/www/html
example-output-df-block-size-mb.txt
Filesystem 1M-blocks Used Available Use% Mounted on
/dev/sda1 51200M 10240M 40960M 20% /

Use case: When you need sizes in a specific unit (MB, GB) for scripting without relying on awk.


19. Sync before reporting

df-sync-before-reporting.sh
df -h --sync
example-output-df-sync.txt
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 10G 40G 20% /

Use case: Forces a filesystem sync first — useful when you need df to reflect very recent writes as accurately as possible.


20. Report across multiple critical paths

df-custom-columns-for-specific-paths.sh
df -h --output=source,fstype,size,used,avail,pcent,target /var/www/html /var/log /var/lib/mysql /mnt/backups
example-output-df-custom-columns-specific.txt
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda1 ext4 50G 10G 40G 20% /
/dev/sdb1 ext4 200G 50G 150G 25% /mnt/backups

Use case: Single-command status check across every partition that matters for WordPress operations.


df vs du

ToolLevelAnswersBest Used For
dfFilesystem"How much space is left on this partition?"Capacity monitoring, alerts
duDirectory tree"Which folder is consuming the space?"Finding the culprit after df warns you

Recommended triage sequence:

  1. df -h — identify which filesystem is filling up.
  2. df -i — rule out inode exhaustion.
  3. du -h --max-depth=1 /mount/point — drill into the filesystem to find the large directory.

Hands-On Practice

Quick Lab (20 Exercises)

  1. Run df -h and identify the filesystem with the highest Use%.
  2. Run df -i and check whether any filesystem has high inode usage.
  3. Run df -h /var/www/html and confirm which mount point hosts WordPress.
  4. Run df -h /var/log and note whether logs share the root partition.
  5. Run df -h /mnt/backups and confirm backups are on a separate device (or not).
  6. Run df -T -h and note the filesystem type for /.
  7. Run df -x tmpfs -h and compare the output to plain df -h.
  8. Run df -t ext4 -h (or your FS type) and observe how filtering changes output.
  9. Run df -P /var/www/html and compare column headings to the default output.
  10. Run df -h --total and verify the grand total row.
  11. Run df --output=source,size,used,avail,pcent,target -h and note readability.
  12. Run df -h . inside your WordPress root and confirm it matches df -h /var/www/html.
  13. Run df -h /var/www/html/wp-config.php and explain why it shows the filesystem, not the file size.
  14. Run df -H and note how numbers differ from df -h.
  15. Run df -h /tmp and check whether it is on the same filesystem as /.
  16. Run df -i /var/www/html and interpret inode usage for the WordPress filesystem.
  17. Run df -h / and record Avail as your current free-space baseline.
  18. Run df -h /var/lib/mysql and determine whether database storage is on a separate mount.
  19. Run df -BM /var/www/html and compare the block sizes against the -h output.
  20. Pair the result with du: choose a mount that is filling up, then run du -h --max-depth=1 inside it.

Task: Build a Monitoring One-Liner

Write a single df command that outputs only the mount point, usage percentage, and available space for /var/www/html, /var/log, and /mnt/backups in a format suitable for pasting into a Slack message.

Solution
df-monitoring-one-liner.sh
df -h --output=target,pcent,avail /var/www/html /var/log /mnt/backups
example-output-monitoring-one-liner.txt
Mounted on Use% Avail
/ 20% 40G
/ 40% 30G
/mnt/backups 25% 150G

Mini Quiz

  1. What is the difference between df and du?
  2. Which df flag shows inode usage instead of block usage?
  3. When would you choose df -H instead of df -h?
  4. Why can file uploads fail even if df -h shows free space?
  5. What does passing a file path to df actually report?
  6. Which option produces POSIX-safe output for use in shell scripts?
  7. How would you exclude tmpfs and devtmpfs from df output?
  8. What does --output=target,pcent,avail produce and why is it useful?

Cheat Sheet
df-cheat-sheet.sh
df -h # Human-readable (1024-based)
df -H # Human-readable (1000-based / decimal)
df -i # Inode usage
df -T -h # Show filesystem type
df -t ext4 -h # Only ext4 partitions
df -x tmpfs -x devtmpfs -h # Exclude virtual filesystems
df -l -h # Local filesystems only
df -P /var/www/html # POSIX output for scripting
df -h --total # Grand total row
df -BM /var/www/html # Output in MB units
df --output=source,fstype,size,used,avail,pcent,target -h
df -h --output=target,pcent,avail # Minimal monitoring snapshot
df -h /var/www/html # WordPress root partition
df -h /var/log # Logs partition
df -h /mnt/backups # Backup mount
df -h /var/lib/mysql # Database partition
df -a -h # All filesystems including pseudo
df --sync -h # Sync before reporting

What's Next