| | |

LFCA 38 ๐Ÿง Checking Disk Usage โ€” df, du

A filesystem that fills up causes problems: the logs stop being written, the applications fail, the system can behave unpredictably. The two tools for finding out how much space is used are df and du. They answer different questions. df reports the filesystem-level usage โ€” how much of each mounted filesystem is used, how much is free, and what percentage is full. du reports the directory-level usage โ€” how much space a specific directory or file consumes, broken down by the subdirectories. The two are complementary: df tells you which filesystem is full, and du tells you what is filling it. This chapter covers both commands, their options, the difference between the apparent size and the disk usage, the inode usage, the patterns for finding the large files and directories, and the pitfalls that make the numbers misleading.

Key point: df reports the per-filesystem usage. du reports the per-directory usage. df -h shows the sizes in human-readable units, and df -i shows the inode usage. du -sh <dir> shows the total size of a directory in human-readable units, and du -h --max-depth=1 <dir> shows the per-subdirectory breakdown. The two can disagree: df counts the blocks used by the filesystem, including the deleted files that are still held open, the reserved blocks, and the metadata; du counts the files it can see, and it does not see the deleted-but-open files. The disagreement is a diagnostic signal, and the lsof +L1 command finds the deleted-but-open files.


The df command

The df command reports the disk space usage for each mounted filesystem. Its name stands for “disk free,” and its output is the per-filesystem summary.

df -h
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/sda2       100G   45G   50G  48% /
# /dev/sda3       400G  120G  280G  30% /home
# /dev/sda1       512M   10M  502M   2% /boot/efi
# tmpfs           7.8G     0  7.8G   0% /dev/shm

The columns are the filesystem, the total size, the used space, the available space, the usage percentage, and the mount point. The -h flag makes the sizes human-readable.

Why the -h flag is the default in practice. The raw output is in 1K blocks, which is hard to read. The -h flag converts the sizes to the human-readable units โ€” K, M, G, T โ€” and it is the form that is used in practice.

Why the filesystem column shows the device. The first column is the device or the pseudo-filesystem. The tmpfs is the memory-backed filesystem, and it is not on a disk. The overlay is the container’s filesystem. The column shows what the mount is backed by.

Why the “Use%” column is the important one. The percentage is the fraction of the usable space that is used. A filesystem at 100% cannot accept new writes, and the applications that need to write fail. The percentage is the first number to check.

Why the “Avail” column is not the “Size” minus the “Used”. The difference is the reserved blocks. The ext4 filesystem reserves 5% of the space for the root user by default, and the reserved space is not available to the regular users. The Avail is what the regular users can use, and the Used plus the Avail is less than the Size.

df -h /
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/sda2       100G   45G   50G  48% /

The 100G minus the 45G is 55G, but the Avail is 50G. The missing 5G is the reserved space.

Why the reserved space is adjustable. The tune2fs -m <percent> command changes the reserved percentage. A data filesystem that does not have the root writing to it can set the reserve to 0, and the space is available.

sudo tune2fs -m 0 /dev/sdb1

Why the df -i shows the inodes. The -i flag reports the inode usage instead of the block usage. A filesystem can run out of inodes even when there is free space.

df -i
# Filesystem      Inodes  IUsed   IFree IUse% Mounted on
# /dev/sda2      6400000 100000 6300000    2% /
# /dev/sda3     25600000 500000 25100000    2% /home

The inode exhaustion is a common problem with the filesystems that hold millions of tiny files, and the df -i is the check.

Why the df -T shows the filesystem type. The -T flag adds the type column, which is useful for the diagnosis.

df -T
# Filesystem     Type     1K-blocks    Used Available Use% Mounted on
# /dev/sda2      ext4     102400000 5000000  95000000   5% /

Why the df can report the pseudo-filesystems. The tmpfs, the devtmpfs, the overlay, and the other pseudo-filesystems appear in the output. The -x flag excludes a type, and the -t flag includes a type.

df -h -x tmpfs -x devtmpfs

The exclusion is the way to see only the real filesystems.

Why the df on a file path shows the containing filesystem. The df <path> form reports the filesystem that contains the path, not the path’s usage.

df -h /home/alice/file.txt
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/sda3       400G  120G  280G  30% /home

The output is the /home filesystem, which is the one that holds the file. The df is the filesystem-level tool, and the path is the way to find which filesystem holds it.


The du command

The du command reports the disk usage of a directory or a file. Its name stands for “disk usage,” and its output is the per-directory breakdown.

du -sh /var/log
# 1.2G    /var/log

The -s flag gives the summary (a single total), and the -h flag makes the size human-readable. The output is the total size of the directory.

Why the du is the directory-level tool. The df reports the filesystem, and the du reports the directory. The two answer the different questions, and the du is the tool for finding what is filling the filesystem.

Why the -s flag is the summary. The du without the -s reports every subdirectory, which is a lot of output. The -s summarizes, and the -sh combination is the common form.

Why the --max-depth=1 is the breakdown. The --max-depth=1 flag reports the immediate subdirectories, which is the per-subdirectory breakdown.

du -h --max-depth=1 /var
# 100M    /var/cache
# 1.2G    /var/log
# 500M    /var/lib
# 2.5G    /var

The output shows the subdirectories and their sizes. The breakdown is the way to find the subdirectory that is using the space.

Why the --max-depth can be increased. The --max-depth=2 reports the subdirectories and their subdirectories, which is the deeper breakdown. The depth is the level of detail.

Why the du can be slow. The du reads the directory tree and the metadata of every file. On a large filesystem, the read is slow, and the command takes time. The du on the root filesystem can take minutes.

Why the du can be limited to a type. The --exclude option skips the paths that match a pattern.

du -sh --exclude='*.log' /var

The exclusion is the way to ignore the files that are not relevant to the question.

Why the du reports the disk usage, not the apparent size. The du reports the blocks that the files occupy, which is the space on the disk. A sparse file has a large apparent size and a small disk usage. The --apparent-size flag reports the apparent size instead.

du -sh --apparent-size file.img
du -sh file.img

The two can differ significantly, and the difference is the sparseness.

Why the du on a file reports the file’s size. The du <file> form reports the file’s disk usage, which is the same as the ls -s output.

du -h /var/log/syslog
# 12M     /var/log/syslog

Why the du can be run as a different user. The du reports the files the user can read. A directory that the user cannot read is not counted, and the total is the visible files. The sudo du counts everything.

Why the du can disagree with the df. The du counts the files it can see, and the df counts the blocks the filesystem has allocated. The deleted-but-open files, the reserved blocks, and the metadata are counted by the df and not by the du. The disagreement is the diagnostic signal.


The difference between df and du

The two commands report different numbers, and the difference is the source of the confusion. Understanding the difference is the diagnostic skill.

Aspectdfdu
LevelFilesystemDirectory
SourceThe filesystem’s block accountingThe directory tree
CountsThe allocated blocksThe visible files
Sees deleted-openโœ…โŒ
Sees reserved blocksโœ…โŒ
SpeedFastSlow
UseWhich filesystem is fullWhat is filling it

Why the df sees the deleted-but-open files. A file that is deleted but still held open by a process continues to occupy the space. The filesystem’s block accounting counts the space, and the df reports it. The du walks the directory tree, and the deleted file is not in the tree, so the du does not count it. The difference is the deleted-but-open files.

Why the df sees the reserved blocks. The ext4 filesystem reserves 5% of the space for the root. The reserved space is counted by the df as the used space (from the regular user’s perspective) and not available to the du. The difference is the reserved blocks.

Why the df sees the metadata. The filesystem’s metadata โ€” the inodes, the journals, the block bitmaps โ€” occupies space. The df counts it, and the du does not. The difference is the metadata.

Why the difference matters. The two commands disagree, and the disagreement is the diagnostic. If the df reports a full filesystem and the du reports a small total, the difference is the deleted-but-open files or the reserved blocks. The lsof +L1 command finds the deleted-but-open files, and the tune2fs -l command shows the reserved blocks.

Why the du and the df are both needed. The df tells you which filesystem is full, and the du tells you what is filling it. The two together are the diagnosis, and the single command is the half.

Why the deleted-but-open file is the classic case. A process writes a large log file, the log is deleted, and the process continues to write to the deleted file. The df reports the space as used, and the du does not see the file. The lsof +L1 finds the file, and restarting the process releases the space.

Why the reserved block is the other case. A filesystem at 100% for the regular user has 5% reserved for the root. The df reports the 100% (or the 95% with the reserve), and the du reports the visible files. The tune2fs -m 0 releases the reserve if it is not needed.


The patterns for finding the space

The common questions are “which filesystem is full?” and “what is filling it?” The patterns answer them.

Which filesystem is full?

df -h | sort -k5 -rn | head

The df -h reports the filesystems, and the sort orders them by the use percentage. The head shows the top few. The command is the quick way to find the full filesystem.

What is filling the filesystem?

sudo du -h --max-depth=1 / | sort -hr | head

The du reports the top-level directories, and the sort orders them by the size. The head shows the largest. The command is the starting point, and the largest directory is the next level to explore.

The recursive drill-down.

sudo du -h --max-depth=1 /var | sort -hr | head
sudo du -h --max-depth=1 /var/log | sort -hr | head

The pattern is to start at the root and drill into the largest directory. Each level narrows the search, and the largest file or directory is found.

The largest files.

sudo find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | sort -k5 -hr | head

The find locates the files larger than 100M, and the ls reports the sizes. The sort orders them. The command is the way to find the large files directly, without the directory tree.

The largest directories.

sudo du -h / --max-depth=1 2>/dev/null | sort -hr | head

The du reports the top-level directories, and the sort orders them. The 2>/dev/null suppresses the permission errors.

The inode exhaustion.

df -i | sort -k5 -rn | head

The df -i reports the inode usage, and the sort orders it. The inode exhaustion is the case where the df -h shows the free space and the df -i shows the full inodes.

The deleted-but-open files.

sudo lsof +L1 | grep deleted

The lsof +L1 lists the files with the link count less than 1, which is the deleted files. The grep deleted filters the output. The command is the way to find the files that the df counts and the du does not.

The reserved blocks.

sudo tune2fs -l /dev/sda2 | grep -i reserved

The tune2fs -l shows the filesystem’s parameters, and the grep filters the reserved block count. The command is the way to see the reserve.

Why the patterns are the workflow. The workflow is: the df finds the full filesystem, the du finds the large directory, the find finds the large file, and the lsof finds the deleted-but-open file. The sequence is the diagnosis, and the patterns are the steps.

Why the patterns should be run as root. The du and the find on the whole filesystem need the root to read every directory. The sudo is the prefix, and the 2>/dev/null suppresses the errors from the directories the user cannot read.

Why the patterns should be limited. The du and the find on the whole filesystem are slow. The --max-depth=1 limits the depth, and the -size +100M limits the files. The limits make the commands usable.


Complete Example Session

# ============================================
# PART 1: THE BASIC DF
# ============================================

df -h
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/sda2       100G   45G   50G  48% /
# /dev/sda3       400G  120G  280G  30% /home
# /dev/sda1       512M   10M  502M   2% /boot/efi

# ============================================
# PART 2: THE INODE USAGE
# ============================================

df -i
# Filesystem      Inodes  IUsed   IFree IUse% Mounted on
# /dev/sda2      6400000 100000 6300000    2% /
# /dev/sda3     25600000 500000 25100000    2% /home

# ============================================
# PART 3: THE FILESYSTEM TYPE
# ============================================

df -T
# Filesystem     Type     1K-blocks    Used Available Use% Mounted on
# /dev/sda2      ext4     102400000 5000000  95000000   5% /

# ============================================
# PART 4: THE EXCLUDED PSEUDO-FILESYSTEMS
# ============================================

df -h -x tmpfs -x devtmpfs -x overlay
# Only the real filesystems.

# ============================================
# PART 5: THE DU SUMMARY
# ============================================

du -sh /var/log
# 1.2G    /var/log

# ============================================
# PART 6: THE DU BREAKDOWN
# ============================================

du -h --max-depth=1 /var | sort -hr
# 2.5G    /var
# 1.2G    /var/log
# 500M    /var/lib
# 100M    /var/cache

# ============================================
# PART 7: THE LARGEST DIRECTORIES
# ============================================

sudo du -h --max-depth=1 / 2>/dev/null | sort -hr | head
# 50G     /
# 20G     /home
# 15G     /var
# 10G     /usr
# 2G      /opt

# ============================================
# PART 8: THE LARGEST FILES
# ============================================

sudo find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | sort -k5 -hr | head
# -rw-r--r-- 1 root root 1.5G /var/log/big.log
# -rw-r--r-- 1 root root 500M /var/lib/db/data

# ============================================
# PART 9: THE DELETED-BUT-OPEN FILES
# ============================================

sudo lsof +L1 | grep deleted
# nginx 1234 root 5w REG 8,2 5000000 0 12345 /var/log/nginx/access.log (deleted)

# The file is deleted but nginx still holds it open.
# The df counts the space, and the du does not see the file.
# Restart nginx to release the space.

# ============================================
# PART 10: THE RESERVED BLOCKS
# ============================================

sudo tune2fs -l /dev/sda2 | grep -i reserved
# Reserved block count:     5120000
# Reserved GDT blocks:      1250
# Reserved blocks uid:      0 (user root)
# Reserved blocks gid:      0 (group root)

# ============================================
# PART 11: THE FILESYSTEM CONTAINING A PATH
# ============================================

df -h /home/alice/file.txt
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/sda3       400G  120G  280G  30% /home

# ============================================
# PART 12: WHAT NOT TO DO
# ============================================

# Don't assume the du total equals the df used
# The deleted-but-open files and the reserved blocks cause the difference.

# Don't run the du on the whole filesystem without the depth limit
# It takes a long time.

# Don't run the du without the root on the whole filesystem
# The unreadable directories are not counted.

# Don't ignore the inode usage
# A filesystem with free space can be out of inodes.

# Don't forget the -h flag
# The raw numbers are hard to read.

# Don't assume the df "Used" plus "Avail" equals "Size"
# The reserved blocks are the difference.

The twelve parts cover the basic df, the inode usage, the filesystem type, the exclusions, the du summary, the breakdown, the largest directories, the largest files, the deleted-but-open files, the reserved blocks, the path query, and the anti-patterns.


Quick Reference

The df Command

CommandPurpose
df -hHuman-readable usage
df -iInode usage
df -TFilesystem type
df -h -x tmpfsExclude a type
df -h <path>The filesystem containing the path
df -h | sort -k5 -rnSorted by the use percentage

The du Command

CommandPurpose
du -sh <dir>The total size
du -h --max-depth=1 <dir>The per-subdirectory breakdown
du -sh --exclude='*.log' <dir>Exclude a pattern
du -sh --apparent-size <file>The apparent size
du -h <file>The file’s disk usage

The df Columns

ColumnMeaning
FilesystemThe device or pseudo-filesystem
SizeThe total size
UsedThe used space
AvailThe available space
Use%The used percentage
Mounted onThe mount point

The df vs du

Aspectdfdu
LevelFilesystemDirectory
CountsAllocated blocksVisible files
Deleted-openโœ…โŒ
Reservedโœ…โŒ
SpeedFastSlow
UseWhich is fullWhat is filling it

The Diagnostic Patterns

QuestionCommand
Which filesystem is full?df -h | sort -k5 -rn | head
What is filling it?sudo du -h --max-depth=1 / | sort -hr | head
The largest files?sudo find / -type f -size +100M -exec ls -lh {} \;
The inode exhaustion?df -i | sort -k5 -rn | head
The deleted-open files?sudo lsof +L1 | grep deleted
The reserved blocks?sudo tune2fs -l <dev> | grep -i reserved

Best Practices

โœ… Do This:

# Use -h for the human-readable sizes
df -h                                                         # โœ…

# Check the inode usage on a filesystem with many small files
df -i                                                         # โœ…

# Find the largest directories
sudo du -h --max-depth=1 / 2>/dev/null | sort -hr | head      # โœ…

# Find the largest files
sudo find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null # โœ…

# Check the deleted-but-open files
sudo lsof +L1 | grep deleted                                  # โœ…

# Check the reserved blocks
sudo tune2fs -l /dev/sda2 | grep -i reserved                  # โœ…

# Exclude the pseudo-filesystems
df -h -x tmpfs -x devtmpfs                                    # โœ…

โŒ Don’t Do This:

# Don't assume the du total equals the df used
# The deleted-open files and the reserved blocks differ.      # โš ๏ธ

# Don't run the du on the whole filesystem without the depth limit
sudo du -h /  # slow and verbose                              # โš ๏ธ

# Don't run the du without the root on the whole filesystem
du -sh /  # the unreadable directories are not counted        # โš ๏ธ

# Don't ignore the inode usage
df -h  # a filesystem with free space can be out of inodes    # โš ๏ธ

# Don't assume the df "Used" + "Avail" = "Size"
# The reserved blocks are the difference.                     # โš ๏ธ

# Don't forget the -h flag
df  # the raw numbers are hard to read                        # โš ๏ธ

Common Pitfalls

PitfallProblemSolution
du โ‰  df usedDeleted-open or reservedlsof +L1, tune2fs -l
Slow duLarge tree--max-depth=1
Permission errorsUnreadable dirssudo, 2>/dev/null
Inodes ignoredFree space but no inodesdf -i
Reserved blocks unknownThe missing spacetune2fs -l
Raw numbersHard to read-h
Pseudo-filesystemsCluttered output-x tmpfs

Real-World Examples

1. The basic usage

df -h

2. The inode usage

df -i

3. The directory size

du -sh /var/log

4. The breakdown

du -h --max-depth=1 /var | sort -hr

5. The largest directories

sudo du -h --max-depth=1 / 2>/dev/null | sort -hr | head

6. The largest files

sudo find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | head

7. The full filesystem

df -h | sort -k5 -rn | head

8. The inode exhaustion

df -i | sort -k5 -rn | head

9. The deleted-open files

sudo lsof +L1 | grep deleted

10. The reserved blocks

sudo tune2fs -l /dev/sda2 | grep -i reserved

Visual: The df and the du

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  df -h                                                   โ”‚
โ”‚                                                          โ”‚
โ”‚  Filesystem      Size  Used Avail Use% Mounted on        โ”‚
โ”‚  /dev/sda2       100G   45G   50G  48% /                 โ”‚
โ”‚                                                          โ”‚
โ”‚  The FILESYSTEM level.                                   โ”‚
โ”‚  The blocks the filesystem has allocated.                โ”‚
โ”‚                                                          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  du -sh /                                                โ”‚
โ”‚                                                          โ”‚
โ”‚  42G    /                                                โ”‚
โ”‚                                                          โ”‚
โ”‚  The DIRECTORY level.                                    โ”‚
โ”‚  The files the walk can see.                             โ”‚
โ”‚                                                          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  THE DIFFERENCE                                          โ”‚
โ”‚                                                          โ”‚
โ”‚  df used:  45G                                           โ”‚
โ”‚  du total: 42G                                           โ”‚
โ”‚  Diff:      3G                                           โ”‚
โ”‚                                                          โ”‚
โ”‚  The 3G is the deleted-but-open files, the reserved      โ”‚
โ”‚  blocks, and the metadata.                               โ”‚
โ”‚                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Visual: The Diagnostic Workflow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  1. Which filesystem is full?                            โ”‚
โ”‚       df -h | sort -k5 -rn | head                        โ”‚
โ”‚       โ†’ /dev/sda2 at 95%                                 โ”‚
โ”‚                                                          โ”‚
โ”‚  2. What is filling it?                                  โ”‚
โ”‚       sudo du -h --max-depth=1 / | sort -hr | head       โ”‚
โ”‚       โ†’ /var is the largest                              โ”‚
โ”‚                                                          โ”‚
โ”‚  3. What in /var?                                        โ”‚
โ”‚       sudo du -h --max-depth=1 /var | sort -hr | head    โ”‚
โ”‚       โ†’ /var/log is the largest                          โ”‚
โ”‚                                                          โ”‚
โ”‚  4. What in /var/log?                                    โ”‚
โ”‚       ls -lhS /var/log | head                            โ”‚
โ”‚       โ†’ the large log files                              โ”‚
โ”‚                                                          โ”‚
โ”‚  5. If the numbers do not add up:                        โ”‚
โ”‚       sudo lsof +L1 | grep deleted                       โ”‚
โ”‚       โ†’ the deleted-but-open files                       โ”‚
โ”‚                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Visual: The df vs the du

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  df: THE FILESYSTEM VIEW                                 โ”‚
โ”‚                                                          โ”‚
โ”‚  The block accounting.                                   โ”‚
โ”‚  Counts the deleted-but-open files.                      โ”‚
โ”‚  Counts the reserved blocks.                             โ”‚
โ”‚  Counts the metadata.                                    โ”‚
โ”‚  Fast.                                                   โ”‚
โ”‚                                                          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  du: THE DIRECTORY VIEW                                  โ”‚
โ”‚                                                          โ”‚
โ”‚  The directory tree walk.                                โ”‚
โ”‚  Sees only the visible files.                            โ”‚
โ”‚  Does not see the deleted-but-open files.                โ”‚
โ”‚  Does not see the reserved blocks.                       โ”‚
โ”‚  Slow.                                                   โ”‚
โ”‚                                                          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  THE TWO ARE COMPLEMENTARY                               โ”‚
โ”‚                                                          โ”‚
โ”‚  df: which filesystem is full                            โ”‚
โ”‚  du: what is filling it                                  โ”‚
โ”‚                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Visual: The Inode Exhaustion

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  df -h                                                   โ”‚
โ”‚  /dev/sda2  100G  50G  50G  50%  /                       โ”‚
โ”‚  The filesystem has 50G free.                            โ”‚
โ”‚                                                          โ”‚
โ”‚  touch /tmp/newfile                                      โ”‚
โ”‚  touch: cannot touch '/tmp/newfile': No space left on deviceโ”‚
โ”‚                                                          โ”‚
โ”‚  WHY?                                                    โ”‚
โ”‚                                                          โ”‚
โ”‚  df -i                                                   โ”‚
โ”‚  /dev/sda2  6400000  6400000  0  100%  /                 โ”‚
โ”‚  The inodes are exhausted.                               โ”‚
โ”‚                                                          โ”‚
โ”‚  The free space is the blocks, and the inodes are        โ”‚
โ”‚  the file records. Millions of tiny files exhaust the    โ”‚
โ”‚  inodes even with free blocks.                           โ”‚
โ”‚                                                          โ”‚
โ”‚  Fix: find and remove the small files, or reformat with  โ”‚
โ”‚  more inodes.                                            โ”‚
โ”‚                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Visual: The Deleted-But-Open File

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  df -h /var                                              โ”‚
โ”‚  /dev/sda2  100G  90G  10G  90%  /var                    โ”‚
โ”‚                                                          โ”‚
โ”‚  du -sh /var/log                                         โ”‚
โ”‚  1G    /var/log                                          โ”‚
โ”‚                                                          โ”‚
โ”‚  The df says 90G used.                                   โ”‚
โ”‚  The du says the visible files are 1G.                   โ”‚
โ”‚  The difference is 89G.                                  โ”‚
โ”‚                                                          โ”‚
โ”‚  lsof +L1 | grep deleted                                 โ”‚
โ”‚  nginx 1234 root 5w REG 8,2 89000000000 0 12345 /var/log/nginx/access.log (deleted)โ”‚
โ”‚                                                          โ”‚
โ”‚  nginx holds the deleted 89G file open.                  โ”‚
โ”‚  The df counts it. The du does not.                      โ”‚
โ”‚                                                          โ”‚
โ”‚  Fix: restart nginx to release the file.                 โ”‚
โ”‚                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

CommandLevelReports
df -hFilesystemThe usage per filesystem
df -iFilesystemThe inode usage
df -TFilesystemThe type
du -shDirectoryThe total size
du -h --max-depth=1DirectoryThe breakdown
lsof +L1FileThe deleted-but-open
tune2fs -lFilesystemThe reserved blocks
QuestionCommand
Which filesystem is full?df -h | sort -k5 -rn
What is filling it?du -h --max-depth=1 | sort -hr
The largest files?find / -type f -size +100M
The inode exhaustion?df -i
The deleted-open files?lsof +L1 | grep deleted

Key takeaways:

  • df reports the filesystem-level usage and du reports the directory-level usage โ€” the two answer the different questions, and the two are complementary
  • df -h is the human-readable form โ€” the -i flag reports the inode usage, and the -T flag reports the type
  • du -sh <dir> is the summary and du -h --max-depth=1 <dir> is the breakdown โ€” the breakdown is the way to find the large subdirectory
  • The df and the du can disagree โ€” the difference is the deleted-but-open files, the reserved blocks, and the metadata
  • The deleted-but-open files are counted by the df and not by the du โ€” the lsof +L1 command finds them, and the restart of the holding process releases the space
  • The reserved blocks are counted by the df and not by the du โ€” the ext4 reserve is 5% by default, and the tune2fs -m 0 releases it
  • The inode exhaustion is the case where the df -h shows free space and the df -i shows the full inodes โ€” the millions of tiny files are the cause, and the df -i is the check
  • The diagnostic workflow is the df for the filesystem, the du for the directory, the find for the file, and the lsof for the deleted-open โ€” the sequence is the diagnosis
  • The du on the whole filesystem needs the root and the depth limit โ€” the unreadable directories are not counted without the root, and the full tree is slow without the limit
  • The df “Used” plus “Avail” is not the “Size” โ€” the reserved blocks are the difference, and the tune2fs -l shows them

Remember: The df and the du answer the two halves of the disk usage question. The df tells you which filesystem is full, and the du tells you what is filling it. The two disagree by the deleted-but-open files, the reserved blocks, and the metadata, and the disagreement is the diagnostic. Use the -h flag, check the inodes, limit the du depth, and find the deleted-open files with the lsof. The two commands together are the complete picture.


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!