| |

LFCS 136 ๐Ÿง Disk Usage โ€” df and du

โฑ๏ธ Estimated read: 10 min | |

The previous chapters covered process and system monitoring. This chapter covers the tools that answer the question: where is the disk space going? The df command reports the filesystem-level usage: the total size, the used space, and the available space for each mounted filesystem. The du command reports the directory-level usage: the space consumed by the files and subdirectories under a given path. The LFCS exam tests the distinction between the two, the -h flag for human-readable output, the -i flag for inode usage, and the --exclude and --max-depth flags for du. The critical trap is that the df and du outputs may disagree. A deleted file that is still held open by a process consumes disk space, but it does not appear in du because there is no directory entry. The df shows the usage, and du does not. The lsof +L1 command is the diagnostic tool for this case.

Key point: df reports filesystem usage. du reports directory usage. The -h flag makes both human-readable. The -i flag shows inode usage instead of block usage. The -T flag on df shows the filesystem type. The -x flag on df excludes specific filesystem types. The --max-depth flag on du limits the recursion depth. The --exclude flag on du skips matching paths.


Why df and du require a specific mental model

The filesystem versus directory problem. df reads the filesystem superblock and reports the total, used, and available blocks. du walks the directory tree and sums the block counts of the files. The two are measuring different things. A filesystem can be 100% full while du shows that the visible files only consume half the space. The difference is the deleted-but-open files, the filesystem metadata (inodes, journal), and the reserved blocks (usually 5% for root).

The deleted-but-open file problem. A process opens a file and then the file is deleted. The directory entry is removed, so du does not see it. The process still holds the file descriptor, so the kernel does not free the blocks. df shows the space as used. The lsof +L1 command lists the deleted files that are still open, and the kill of the process (or the restart of the service) releases the space. This is the most common cause of the df/du discrepancy.

The inode problem. A filesystem can be full of inodes while having plenty of block space. Each file consumes one inode, regardless of size. A directory with millions of tiny files can exhaust the inode table. The df -i command shows the inode usage. The du command does not show inode usage; it only shows block usage.

The reserved block problem. The ext4 filesystem reserves 5% of the blocks for the root user. A filesystem at 100% usage for a regular user may be at 95% usage for root. The df output shows the reserved blocks in the used column or in a separate column depending on the version. The tune2fs -m command changes the reserved percentage.

The trade-off. df is fast and reads the superblock. du is slow and walks the tree. The df is the first command to run when the disk is full. The du is the second command, to find the directory that is consuming the space. The du -sh on each top-level directory is the standard drill-down.


a. The df command: filesystem usage

The df command reports the filesystem usage. The default output is in 1K blocks.

df

The output has columns: Filesystem, 1K-blocks, Used, Available, Use%, and Mounted on.

ColumnMeaning
FilesystemThe device or pseudo-filesystem
1K-blocksTotal size in 1K blocks
UsedUsed blocks
AvailableAvailable blocks
Use%Percentage used
Mounted onMount point

The -h flag shows human-readable units (K, M, G). The -T flag shows the filesystem type. The -i flag shows inode usage instead of block usage. The -x flag excludes a filesystem type.

# Human-readable
df -h

# Show filesystem type
df -hT

# Show inodes
df -i

# Exclude tmpfs
df -hx tmpfs

The df -h is the first command when the disk is full. It identifies the filesystem that is at 100% and the mount point. The df -i is the second command if the filesystem is not full of blocks but the application cannot create files. The inode exhaustion is the cause.


b. The du command: directory usage

The du command reports the usage of a directory and its subdirectories. The default output is in 1K blocks, one line per subdirectory.

du

The -h flag shows human-readable units. The -s flag summarizes the total instead of listing each subdirectory. The -c flag produces a grand total. The --max-depth=N flag limits the recursion.

# Total of the current directory
du -sh

# Total of a specific directory
du -sh /var/log

# Top-level directories only
du -h --max-depth=1 /var

# Grand total
du -ch /var/log

The du -sh /var/* is the standard drill-down. It shows the size of each top-level directory under /var, which identifies the directory that is consuming the space. The --max-depth=1 is the equivalent for the current directory.

The --exclude flag skips matching paths. This is useful for excluding large directories that are not the subject of the investigation.

# Exclude .git directories
du -sh --exclude=.git .

The -x flag on du prevents crossing filesystem boundaries. This is useful when a directory contains a mount point for another filesystem, which would otherwise be counted in the parent’s total.

# Do not cross filesystem boundaries
du -shx /

c. Diagnosing the df/du discrepancy

The df and du outputs disagree when a file is deleted but still open, or when the filesystem has reserved blocks. The diagnostic steps are:

  1. Run df -h to identify the filesystem that is full.
  2. Run du -shx <mount-point>/* to find the directory that is consuming the space.
  3. If the du total is much smaller than the df usage, run lsof +L1 to find the deleted-but-open files.
  4. Restart the process that holds the deleted file, or kill it, to release the space.

The lsof +L1 command lists the files with a link count less than 1, which is the marker for a deleted-but-open file.

# List deleted-but-open files
sudo lsof +L1

# Alternative: find deleted files in /proc
sudo ls -l /proc/*/fd/* 2>/dev/null | grep deleted

The lsof output shows the process name, the PID, the user, the file descriptor, and the size of the deleted file. The kill of the process or the restart of the service releases the space.

The reserved blocks are the other source of the discrepancy. The ext4 filesystem reserves 5% of the blocks for the root user by default. The df shows the reserved blocks as used, but du does not count them.

# Check the reserved block percentage
sudo tune2fs -l /dev/sda1 | grep "Reserved block count"

# Change the reserved percentage (e.g., to 1%)
sudo tune2fs -m 1 /dev/sda1

Complete Example Session

# ============================================
# PART 1: CHECK FILESYSTEM USAGE
# ============================================

df -h
# Shows the usage of each filesystem.
# Identify the filesystem at 100%.
# ============================================
# PART 2: CHECK INODE USAGE
# ============================================

df -i
# Shows the inode usage.
# If inodes are at 100%, the filesystem is full of small files.
# ============================================
# PART 3: FIND THE LARGE DIRECTORY
# ============================================

du -sh /var/* 2>/dev/null
# Shows the size of each top-level directory.
# ============================================
# PART 4: DRILL DOWN
# ============================================

du -sh /var/log/* 2>/dev/null | sort -h
# Shows the size of each directory under /var/log, sorted.
# ============================================
# PART 5: FIND THE LARGEST FILES
# ============================================

find /var -type f -exec du -h {} + 2>/dev/null | sort -h | tail -10
# Shows the 10 largest files.
# ============================================
# PART 6: CHECK DELETED-BUT-OPEN FILES
# ============================================

sudo lsof +L1
# Lists files with link count < 1.
# ============================================
# PART 7: RELEASE THE SPACE
# ============================================

sudo systemctl restart <service>
# Or kill the process that holds the deleted file.
# ============================================
# PART 8: CHECK RESERVED BLOCKS
# ============================================

sudo tune2fs -l /dev/sda1 | grep "Reserved block count"
# Shows the reserved blocks.
# ============================================
# PART 9: EXCLUDE FILESYSTEMS
# ============================================

du -shx /
# Does not cross into other filesystems.

The nine parts trace the disk usage diagnosis: df, df -i, du drill-down, find largest files, lsof +L1, release space, reserved blocks, and du -x.


Quick Reference

df Options

OptionPurpose
-hHuman-readable
-TShow filesystem type
-iShow inode usage
-x <type>Exclude filesystem type
-aShow all filesystems

du Options

OptionPurpose
-hHuman-readable
-sSummary total
-cGrand total
-xDo not cross filesystems
--max-depth=NLimit recursion
--exclude=<pattern>Skip matching paths
-aShow files, not just directories

Diagnostic Commands

CommandPurpose
lsof +L1Deleted-but-open files
tune2fs -lFilesystem metadata
tune2fs -m NReserved block percentage

Common Patterns

CommandUse Case
df -hFirst command when disk is full
du -sh /*Drill down to the large directory
df -iInode exhaustion
du -shx /Exclude mount points

Best Practices

โœ… Do This:

df -h
<!-- Check filesystem usage first -->                # โœ…
du -sh /var/* | sort -h
<!-- Sort directories by size -->                    # โœ…
sudo lsof +L1
<!-- Check for deleted-but-open files -->            # โœ…

โŒ Don’t Do This:

# Assume df and du always agree
<!-- Deleted files are invisible to du -->           # โŒ
# Run du on the entire filesystem without -x
<!-- Crosses into other mounts -->                   # โŒ
# Ignore inode usage
<!-- df -h can show free space when inodes are full --> # โŒ

Common Pitfalls

PitfallWhy It HappensFix
df full, du shows lessDeleted-but-open fileslsof +L1
Cannot create filesInodes exhausteddf -i
du slow on large filesystemWalks the treeUse --max-depth=1
Mount point counted twiceNo -x flagdu -x
Reserved blocks invisible5% reserved for roottune2fs -m 1

Real-World Examples

1. Check Disk Usage

df -h

2. Check Inodes

df -i

3. Directory Size

du -sh /var/log

4. Top Directories

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

5. Largest Files

find /var -type f -exec du -h {} + | sort -h | tail

6. Deleted Files

sudo lsof +L1

7. Exclude Filesystem

du -shx /

8. Exclude Pattern

du -sh --exclude=.git .

9. Reserved Blocks

sudo tune2fs -l /dev/sda1 | grep Reserved

10. Change Reserved

sudo tune2fs -m 1 /dev/sda1

Visual

df vs du

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  df -h                                       โ”‚
โ”‚  โ†’ Filesystem level                          โ”‚
โ”‚  โ†’ Reads superblock                          โ”‚
โ”‚  โ†’ Fast                                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  du -sh                                      โ”‚
โ”‚  โ†’ Directory level                           โ”‚
โ”‚  โ†’ Walks the tree                            โ”‚
โ”‚  โ†’ Slow                                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Deleted-But-Open File

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Process opens file.log                      โ”‚
โ”‚  File is deleted                             โ”‚
โ”‚  Process holds file descriptor               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  df: used space still reported               โ”‚
โ”‚  du: file not visible                        โ”‚
โ”‚  lsof +L1: shows the file                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Restart process โ†’ space released            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
Filesystem usagedf
Directory usagedu
Human-readable-h
Inode usagedf -i
Filesystem typedf -T
Deleted-but-open fileslsof +L1
Exclude mount pointsdu -x
Limit depth--max-depth=N

Key takeaways:

  • df and du measure different things. df reads the filesystem superblock. du walks the directory tree. They can disagree when deleted files are still held open, or when reserved blocks are in use.
  • The deleted-but-open file is the most common discrepancy. du does not see the file because the directory entry is gone. lsof +L1 shows the file, and restarting the process releases the space.
  • Inode exhaustion is a separate failure. df -h can show free space while the filesystem cannot create new files because the inode table is full. df -i shows the inode usage.
  • The du drill-down is the diagnostic. du -sh /var/* shows the top-level directories. The --max-depth=1 limits the recursion. The -x flag prevents crossing mount points.
  • The reserved blocks are invisible to du. The ext4 filesystem reserves 5% of the blocks for root. The tune2fs -m changes the percentage.

Remember: df is the filesystem. du is the directory. The -h is human. The -i is inodes. The -x is the boundary. The lsof +L1 is the deleted file. The exam tests the difference and the diagnostic sequence.

Was this helpful?


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!