“Disk full” is not a diagnosis. It is a symptom that can interrupt package updates, databases, logging, containers, and ordinary file writes. The fastest route back to a healthy system is not to delete whatever looks large. It is to identify the full filesystem first, then trace the directories that consume space inside that filesystem.
On GNU/Linux, df and du are the standard first pair of tools for this job. They answer different questions. df reports space used and available on mounted filesystems. du estimates the space used by files and directories in a path. Running them in the right order turns a vague storage problem into a bounded investigation.
This guide stays deliberately conservative. It shows how to collect evidence, narrow the search, and recognize when the result needs a service-specific retention change rather than a broad cleanup command. It does not recommend automatic deletion, recursive removal, or clearing directories whose owner and purpose are unknown.
- The different jobs of df and du
- Find the filesystem that is actually constrained
- Walk the directory tree without crossing mounts
- Read size output and sort it correctly
- Explain common mismatches before deleting anything
- Turn findings into safe corrective action
Start with the filesystem, not a directory
The GNU df documentation defines the command’s role plainly: it reports the used and available space on filesystems. With no argument, it reports mounted filesystems; with a path, it reports the filesystem that contains that path. That makes df the first command when a service reports no space left.
Use a readable overview first:
df -hT
-h formats sizes for people, using powers of 1024, and -T includes the filesystem type. Look for the row with the high use percentage and note its Mounted on column. A full root filesystem mounted at / is a different investigation from a full data volume mounted at /srv, /home, or /var/lib/docker.
Do not infer the target from a directory name alone. /home might be part of the root filesystem on one machine and a separate mounted volume on another. Likewise, a large external, network, container, or bind mount can appear under a directory tree without consuming capacity from the root filesystem. df establishes the boundary before du starts counting beneath it.
When an application says it cannot create files but the percentage looks ordinary, check inode use as well:
df -i
An inode records metadata about a file, including ownership, permissions, timestamps, and its filesystem location. A filesystem can run out of inodes after accumulating a very large number of tiny files even when blocks remain available. GNU df documents -i as a switch from block usage to inode usage. The corrective path for an inode problem is still evidence-first: locate the generator of the file count and fix its retention or behavior rather than deleting random files.
Save the output of df -hT and, when relevant, df -i. After a targeted fix, the same commands make it clear whether capacity or inode pressure actually improved.
Use du to map the consumption inside that boundary
Once df identifies the affected mount point, du helps locate the large branches beneath it. GNU’s documentation for du explains that, with no arguments, it reports the storage needed for files at or below the current directory. In its normal mode, it describes filesystem usage rather than only the apparent length of file contents.
For a root filesystem that is genuinely mounted at /, begin with a one-level summary:
sudo du -xhd1 /
The options are purposeful:
-d1limits the display to one directory level, keeping the first pass readable.-hmakes the totals easier to scan.-xkeeps the walk on one filesystem, so a separately mounted/home,/mnt, or network mount does not dominate a root-filesystem investigation.sudocan reveal directories that an ordinary account cannot read; use it only on systems you are authorized to administer.
Find the large branch, then descend one level at a time. If /var is substantial, for example, run:
sudo du -xhd1 /var
Then repeat the pattern for the largest child, such as a log, cache, package, database, or application-data directory. This is slower than issuing a broad deletion command and much safer. It preserves the question that matters: which component owns this data, and what retention behavior created it?
For a quick total of one known path, use summary mode:
sudo du -xsh /var/log
GNU du documents -s as displaying only a total for each argument. It is useful for comparing a few suspected locations, but it cannot replace a directory-level walk when the source of the growth is unknown.
Sort readable sizes correctly
A one-level report is often easier to read when sorted. This command keeps the same filesystem boundary and orders the human-readable totals:
sudo du -xhd1 /var | sort -h
The -h option for GNU sort is a human-numeric sort. It understands the scale suffixes produced by a single human-readable df, du, or ls invocation, so 900M sorts before 1.1G rather than as plain text. Use tail only after you have confirmed the report itself is scoped to the filesystem and directory you intend to inspect.
There is a practical distinction between a useful inventory and an expensive scan. A recursive du over a very large tree can take time and create significant disk activity, especially on busy storage or remote mounts. Start at one level. Narrow only the branch that explains the observed pressure. Avoid running a wide scan inside an application’s hot data path during a performance-sensitive period unless that investigation is necessary and approved.
Hidden directories are another reason to prefer du -d1 over a shell glob such as path/*. A basic glob can omit names beginning with a dot, while the directory walk accounts for the tree beneath the named starting point. The point is completeness, not cleverness.
Understand what a number represents
The number shown by du is not always the same as the apparent file size shown by a file listing. GNU Coreutils documents --apparent-size as a mode that prints apparent sizes rather than filesystem usage. This distinction is especially important for sparse files: a sparse file can have a large logical length while using little physical disk space because parts of the file have no stored blocks.
Use the normal du result when diagnosing a filesystem that is actually filling. Compare it with apparent size only when the difference itself is the question:
du -sh /path/to/data
du --apparent-size -sh /path/to/data
Different results are not an error. They describe two different measurements. The normal view is about allocated filesystem space; apparent size is about the logical length of regular files and symbolic links. Compression, sparse allocation, filesystem block rounding, and hard links can all make a simplistic “file size equals disk use” assumption misleading.
Do not use the comparison as a deletion signal on its own. It should lead to a more precise question, such as whether a virtual-disk image is sparse by design or whether an application is writing unexpectedly large real data.
When df and du do not seem to agree
It is common to expect the totals from du to match df exactly. They measure related but not identical views, and the scope of the commands matters. Before treating a mismatch as corruption, check the basics:
- Are you walking the same filesystem that
dfidentified? Use-xand start at the reported mount point. - Could permissions hide directories from a non-privileged scan? Re-run only if administrative access is appropriate.
- Are there nested mounts or bind mounts? A directory path can contain a different mounted filesystem whose capacity belongs elsewhere.
- Are you comparing allocated use with apparent size? Keep the measurement mode consistent.
- Did an application retain data that needs service-aware maintenance? Logs, databases, package caches, containers, snapshots, and application uploads all have owners and retention rules.
A large log directory is a good illustration. The right response is not necessarily to delete files by name. First identify the producing service, inspect whether its rotation or retention policy is working, and decide whether the data must be retained for operations, auditing, or recovery. The guide to reading Linux logs with journalctl provides context for inspecting systemd journal data without confusing log investigation with blanket cleanup.
Similarly, a container host, a database server, and a desktop package cache need different remediation paths. A useful disk-use report tells you where to look; it does not grant permission to remove the contents of a directory.
Turn the finding into one safe action
After the largest consumer is known, choose the smallest fix that addresses the owner of the data. That might mean correcting log retention, moving a data directory to a larger filesystem, completing a failed backup export, pruning genuinely unused application artifacts through the owning tool, or expanding storage through the platform’s supported method.
Keep the sequence disciplined:
- Record
df -hTand, if relevant,df -i. - Run a one-level
du -xhd1report from the affected mount point. - Narrow only the largest unexplained branch.
- Identify the application, service, user workflow, or retention rule that owns the data.
- Apply one supported, reversible corrective action where possible.
- Run the same
dfcommand again and verify that the expected filesystem improved.
For a concise reference to the basic commands themselves, see 20 essential Linux terminal commands. This article’s added value is the decision order: filesystem first, directory tree second, ownership and remediation last.
Conclusion
df and du are powerful because they reduce disk pressure to evidence. df tells you which mounted filesystem is constrained. du shows where its capacity is being consumed. Options such as -x, -d1, -s, and human-numeric sorting keep the investigation bounded and readable.
The important habit is not memorizing a cleanup command. It is maintaining the separation between observation and action. Measure the correct filesystem, narrow its tree methodically, understand what the reported number means, and make the eventual fix in the tool or policy that owns the data. That is how a full filesystem becomes a manageable operational problem rather than a risky deletion session.



