du Command in Linux (With Examples)

Analyze disk usage with the Linux du command. Covers summaries, output sorting, file exclusions, timestamps, and troubleshooting.

Last updatedAuthorJoshua JamesRead time8 minGuide typeLinux Commands

When a filesystem starts filling up, the du command in Linux tells you which directories and files are actually consuming space. It is useful for checking log growth, comparing project folders, and separating real disk usage from noisy guesses before you delete anything.

Because du ships with GNU coreutils on most Linux systems, installation rarely needs attention. The examples focus on summaries, units, depth limits, exclusions, sorting pipelines, symlink behavior, and the common cases where du and df disagree.

Understand the du Command Syntax and Options

Basic du Syntax

The du command follows this basic pattern:

du [OPTIONS] [FILE_OR_DIRECTORY...]

When run without arguments, du recursively walks the current directory and prints the disk usage of every subdirectory in 1024-byte (1 K) blocks. Adding options changes the output unit, depth, or format. You can pass one or more paths to check specific locations instead of the current directory.

Verify du Is Available

The du command ships as part of GNU coreutils on most Linux distributions. Confirm that your shell resolves the GNU command by checking the first version line:

du --version | head -n 1

A GNU system returns a line like this, although the version number can differ:

du (GNU coreutils) 9.4

For the local reference page, run man du; when man pages are unavailable, use du --help. The GNU Coreutils du manual documents the long options used here, including --max-depth, --apparent-size, --threshold, and --exclude. Minimal BusyBox systems usually expose a smaller du applet; run du --help there and avoid GNU-only options such as --time, --apparent-size, and --exclude.

Essential du Options Quick Reference

OptionDescriptionExample
-hHuman-readable sizes (K, M, G)du -h ~/projects
-sShow only the total for each argumentdu -sh ~/Documents
-cPrint a grand total at the enddu -ch ~/Downloads ~/Documents
-aInclude individual files, not just directoriesdu -ah ~/projects
-d NLimit output to depth Ndu -hd1 ~/projects
-kDisplay sizes in kilobytesdu -sk ~/Downloads
-mDisplay sizes in megabytesdu -sm ~/Downloads
--timeShow last modification timestampdu -h --time ~/projects
--excludeSkip files matching a patterndu -sh --exclude='*.log' ~/projects
-t SIZEExclude entries below (or above, if negative) a thresholddu -h -t 100M ~
--apparent-sizePrint file sizes rather than disk allocationdu --apparent-size -sh ~/data
-LFollow symbolic linksdu -shL ~/linked-dir
-xStay on one filesystem (skip mount points)sudo du -shx /

Display du Disk Usage Summaries

The most common du use case is checking how much space a directory consumes. The -s (summarize) flag collapses the output to a single total, and -h (human-readable) converts raw block counts to K/M/G units.

Summarize the Current Directory

du -sh
2.2M    .

The output shows the total size of the current working directory in human-readable format. Without -h, the number would appear as raw 1 K blocks.

Include Hidden Files in du Output

The du total includes hidden files and directories by default when it scans a directory. Shell globs such as * can skip dotfiles, so point du at the directory itself when hidden entries matter.

du -ah . | sort -rh | head -10

Example output can include dot-directories and dotfiles alongside normal paths:

24M     .
12M     ./.cache
8.0M    ./project
4.0M    ./.config/settings.json

Check a Specific Directory

Pass a path to check a directory other than the current one:

du -sh ~/Downloads
1.4G    /home/user/Downloads

This is useful for quickly auditing well-known directories such as ~/Downloads, ~/Documents, or a project checkout without navigating into them first.

Summarize Multiple Directories at Once

You can pass several paths in a single command. Add -c to include a grand total at the end:

du -csh ~/Downloads ~/Documents ~/Pictures
1.4G    /home/user/Downloads
620M    /home/user/Documents
2.2G    /home/user/Pictures
4.2G    total

The -c flag adds the “total” line, which is helpful when comparing several locations in a single glance.

Control du Output Units

By default, du reports sizes in 1024-byte blocks. You can force specific units with dedicated flags or the flexible -B (block-size) option.

Fixed Unit Flags

Use -k for kilobytes or -m for megabytes when you need consistent units for scripting or reports:

du -sk ~/Downloads
1468006 /home/user/Downloads
du -sm ~/Downloads
1434    /home/user/Downloads

These flags output plain numbers without unit suffixes, which makes the output easier to parse in scripts with tools like awk or cut.

Custom Block Size with -B

The -B flag scales output to any block size. Common suffixes are K (1024), M (1048576), and G (1073741824):

du -sB G ~
5       /home/user

The number shown is rounded up to the nearest whole block. For decimal output, prefer -h instead.

Limit du Directory Depth with --max-depth

Running du on a large directory tree can produce thousands of lines. The GNU -d option, written long-form as --max-depth, restricts how many levels deep the output goes. Depth 0 is the starting path, so --max-depth=0 behaves like -s.

Show Top-Level Subdirectory Sizes

Set depth to 1 to see immediate children only:

du -hd1 ~/projects
16M     /home/user/projects/app
48M     /home/user/projects/assets
4.0K    /home/user/projects/scripts
64M     /home/user/projects

This immediately reveals which subdirectory is consuming the most space without listing every nested file.

Use Depth 0 as a Summary Alternative

Setting -d0 is equivalent to -s. Both produce a single total for the target path:

du -hd0 ~/projects
64M     /home/user/projects

Display Modification Timestamps with du

The --time flag adds a modification timestamp column to the output, which helps identify which directories or files were recently changed.

Show Timestamps for Subdirectories

du -h --time ~/projects
16M     2026-01-15 08:30    /home/user/projects/app
48M     2026-02-10 11:00    /home/user/projects/assets
64M     2026-02-10 11:21    /home/user/projects

The timestamp reflects the most recent modification of any file within that directory.

Show Timestamps for Individual Files

Combine --time with -a (all files) to see per-file timestamps:

du -ah --time ~/Documents/*.pdf
2.4M    2025-11-20 14:33    /home/user/Documents/report.pdf
512K    2026-01-05 09:12    /home/user/Documents/invoice.pdf

The --time flag is a GNU extension. BusyBox (Alpine Linux) and BSD (macOS) versions of du do not support it. On macOS, use stat -f "%z %Sm %N" * as an alternative.

Exclude Files and Directories with du

The --exclude flag filters files matching a shell glob pattern from the output. This is useful when you want disk usage without counting temporary files, logs, or caches.

Exclude by File Extension

To check a directory’s size while ignoring .log files, quote the pattern to prevent the shell from expanding the glob:

du -sh --exclude='*.log' ~/projects
58M     /home/user/projects

Always wrap --exclude patterns in single quotes. Without quoting, the shell may expand *.log to matching filenames in the current directory before du sees the pattern, causing unexpected results.

Exclude Multiple Patterns

Repeat --exclude for each pattern you want to skip:

du -sh --exclude='*.log' --exclude='*.tmp' --exclude='*.cache' ~/projects

For a long list of patterns, create a small pattern file and pass it with --exclude-from. This command overwrites ~/du-excludes-example.txt if it already exists:

printf '%s\n' '*.log' '*.tmp' '*.cache' '*.bak' > ~/du-excludes-example.txt

The file contains one exclude pattern per line:

*.log
*.tmp
*.cache
*.bak
du -sh --exclude-from="$HOME/du-excludes-example.txt" ~/projects

This cleanup removes only the pattern file created in this section. Keep the file if you plan to reuse the same exclude list later.

Remove the temporary pattern file when you finish testing --exclude-from:

rm ~/du-excludes-example.txt

Verify the file is gone:

test ! -e ~/du-excludes-example.txt && echo "du-excludes-example.txt removed"
du-excludes-example.txt removed

Filter by Size Threshold

The -t (threshold) option excludes entries below a given size. Use this to focus on only the large consumers:

du -h -t 100M --max-depth=1 ~
1.4G    /home/user/Downloads
620M    /home/user/Documents
2.2G    /home/user/Pictures
4.2G    /home/user

Only directories consuming 100 MB or more appear in the output. A negative threshold (e.g., -t -50M) shows entries smaller than the value instead.

Combine du with Other Commands

Piping du output into other utilities unlocks sorting, filtering, and formatting capabilities that du alone does not provide.

Sort Directories by Size

Pipe the output of du into sort -rh to rank directories from largest to smallest:

du -hd1 ~/projects | sort -rh
64M     /home/user/projects
48M     /home/user/projects/assets
16M     /home/user/projects/app
4.0K    /home/user/projects/scripts

The -r flag reverses the order (largest first) and -h tells sort to interpret human-readable suffixes (K, M, G) correctly.

Find the Largest Files in a Directory

Combine -a (all files) with sort and head to display only the top consumers:

du -ah ~/projects | sort -rh | head -10
64M     /home/user/projects
48M     /home/user/projects/assets
24M     /home/user/projects/assets/video-cache
16M     /home/user/projects/app
8.0M    /home/user/projects/app/build.log
4.0M    /home/user/projects/app/database.sql
4.0K    /home/user/projects/scripts

This pipeline is one of the fastest ways to pinpoint exactly where disk space is going.

Filter du Output with grep

Use the grep command in Linux to isolate specific subdirectories from verbose output:

du -h --max-depth=2 ~ | grep -E '^[[:space:]]*[0-9.]+G'

Example output shows only matching gigabyte-sized entries:

2.2G    /home/user/Pictures
1.4G    /home/user/Downloads

This filters the output to show only entries measured in gigabytes, helping you quickly spot heavy subdirectories within your home directory.

Advanced du Techniques

Apparent Size vs Disk Usage

By default, du reports disk usage, meaning the blocks the filesystem actually allocates. The --apparent-size flag shows the logical byte size instead, closer to what tools such as ls -l report for regular files:

du -sh ~/database.sql
52M     /home/user/database.sql
du --apparent-size -sh ~/database.sql
50M     /home/user/database.sql

The difference occurs because filesystems allocate space in fixed-size blocks. A 50 MB file on a filesystem with 4 K blocks may occupy 52 MB of actual disk allocation. Sparse files can show the opposite: apparent size larger than disk usage, because the file has logical holes that do not consume real blocks yet.

Handle Symbolic Links

By default, du does not follow symbolic links (-P behavior). To follow them and count the target’s size instead, use -L:

du -shL ~/linked-dir

Be cautious with -L on trees with many symlinks. Following links can cross into paths you did not intend to measure, and recursive link loops can produce diagnostics instead of a clean size report.

Stay on One Filesystem

When scanning from the root directory, du crosses into every mounted filesystem (NFS shares, USB drives, /proc, /sys) by default. The -x flag restricts du to the same filesystem as the starting path:

sudo du -shx /

This gives the true disk consumption of the root filesystem without including mounted volumes. The sudo prefix is needed to read directories owned by other users, such as /root and service accounts.

Count Hard Links Separately

The -l flag tells du to count hard-linked files each time they appear rather than counting shared blocks only once. This is useful for auditing how much space a directory’s files would consume if copied without preserving hard links:

du -slh ~/backups

Without -l, hard-linked files sharing the same inode contribute their block count only once to the total.

Troubleshoot Common du Errors

“Permission denied” Messages

When du encounters directories your user account cannot read, it prints a warning and skips those paths. A direct scan of a root-owned directory often shows the problem:

du -sh /root

Relevant output includes the permission warning:

du: cannot read directory '/root': Permission denied

This commonly happens when scanning system directories such as / or /var. To include all readable system paths in the total, run du with elevated privileges and keep the scan on the same filesystem:

sudo du -shx /

Example output shows one total for the root filesystem:

18G     /

GNU du does not have a dedicated --ignore-errors flag. To suppress warnings without using sudo, redirect standard error, but remember that this hides all diagnostic messages from that command:

du -sh /var 2>/dev/null

“No such file or directory” Errors

If a file or directory is deleted while du is running, or you pass a path that does not exist, du reports the missing path:

du -sh /tmp/session_abc123
du: cannot access '/tmp/session_abc123': No such file or directory

This is common in directories with rapidly changing contents, like /tmp. The error is informational when other paths still produce totals. For scripted checks, confirm the path exists before running du:

test -e /tmp/session_abc123 && du -sh /tmp/session_abc123 || echo "Path not found"
Path not found

Use stderr redirection only when the changing paths are expected and the remaining totals are still useful.

du and df Report Different Sizes

A common source of confusion is that du -sh / and df -h / often show different numbers. The reasons include:

  • Deleted-but-open files: When a process holds a file descriptor to a deleted file, df still counts the space as used, but du cannot see the file. Restart the process or use lsof +L1 to find these.
  • Filesystem metadata: df accounts for space consumed by journal logs, superblocks, and reserved blocks that du does not report.
  • Mount points: Without -x, du may follow mount points and count space on other filesystems.
  • Sparse files: du reports actual disk allocation, while ls -l shows apparent size. Use du --apparent-size to compare.

To find deleted-but-open files that are holding space, run:

sudo lsof +L1 | head -20

du Takes Too Long on Large Filesystems

Scanning millions of files with du can take minutes. Speed up the first pass by limiting depth, staying on one filesystem, and sorting only the top-level result:

sudo du -xhd1 / | sort -rh | head -20

Example output lists the largest top-level directories first:

18G     /
8.2G    /usr
5.1G    /var
3.2G    /home

The -x flag prevents crossing into mounted filesystems, and -d1 limits output to the top-level directories. For interactive exploration of large directory trees, consider a tool like ncdu, which provides a navigable interface.

Conclusion

Disk usage checks are easier once du -sh, --max-depth, exclusions, and sorting pipelines are part of your terminal workflow. For deeper cleanup triage, the du disk usage analysis examples build on these basics with larger real-world scans.

Share this guide

Help another Linux user troubleshoot faster

Share this guide with someone troubleshooting Linux systems or saving it for later.

Follow LinuxCapable

Want more LinuxCapable guides in Google?

Add LinuxCapable as a preferred source so Google can show more of our fresh Linux tutorials in Top Stories and From your sources when relevant.

Add LinuxCapable as a preferred source on Google
Search LinuxCapable

Need another guide?

Search LinuxCapable for package installs, commands, troubleshooting, and follow-up guides related to what you just read.

Found this guide useful?

Support LinuxCapable to keep tutorials free and up to date.

Buy me a coffeeBuy me a coffee
Before commenting, please review our Comments Policy.
Formatting tips for your comment

You can use basic HTML to format your comment. Useful tags currently allowed in published comments:

You type Result
<code>command</code> command
<strong>bold</strong> bold
<em>italic</em> italic
<blockquote>quote</blockquote> quote block

Got a Question or Feedback?

We read and reply to every comment - let us know how we can help or improve this guide.

Verify before posting: