Linux disk usage can look confusing when df reports a nearly full filesystem but du cannot find enough visible files to explain it. The tools measure different things: df reports filesystem allocation information, while du estimates usage for the file and directory trees it can traverse. Their outputs are related, but they are not interchangeable inventories.
This guide provides a read-first troubleshooting workflow for systems you administer. Avoid deleting unfamiliar files or restarting a service solely to make a number smaller. Establish which filesystem is affected and why space is allocated before choosing a remedy.
1. Identify the affected filesystem
Begin with a filesystem overview and the path that is failing:
df -h /path/to/application
The path should be replaced with the relevant application directory. The output tells you which mounted filesystem supplies that location and its reported size, use, and availability. Do not assume that the root filesystem, a data volume, and a container’s writable layer share the same capacity.
Check the mount structure through your normal system tools. Separate mount points can make a directory look like part of one tree while its data belongs to another filesystem. Network mounts and container storage add further layers that require platform-specific interpretation.
Record the observation time and the workload’s behavior. A rapidly growing log or temporary export can change usage during an investigation, making sequential commands appear inconsistent even when both are correct.
2. Compare Linux disk usage within a consistent boundary
Use du on the relevant tree rather than scanning every mounted filesystem without a purpose. On GNU systems, a first-level summary might look like:
du -x -h --max-depth=1 /path/to/application
The one-filesystem option limits traversal across filesystem boundaries. The depth option helps identify which immediate child directories deserve closer inspection. Check your platform’s documentation because options can differ outside GNU coreutils.
Do not suppress permission errors without understanding their impact. If du cannot read part of the tree, its summary may omit data. Use approved administrative access when needed, and keep the scan scoped so it does not interfere unnecessarily with a busy production service.
Compare similar units and measurement concepts. Human-readable sizes are convenient but rounded. For a precise investigation, use consistent units and distinguish allocated storage from a file’s apparent logical length.
3. Look for deleted files still held open
On typical Linux filesystems, removing a directory entry does not immediately free an open file’s storage while a process still holds it. A service may continue writing to a deleted log, so the allocation remains visible to df while an ordinary directory walk cannot find the old pathname.
Use an approved open-file inspection tool to identify deleted files and their owning processes. Review the process, file size, and operational role before acting. The right remedy may be a supported log-reopen operation or a planned service restart, not a broad process-killing command.
Fix the rotation behavior that caused the condition. A recurring manual restart treats the symptom without ensuring the service closes or reopens its log correctly. Document the supported application procedure and test it during maintenance.
4. Check inode capacity as well as byte capacity
A filesystem can run out of inodes even while byte capacity remains available. Workloads that generate huge numbers of small files are common causes. Inspect inode usage with the relevant filesystem report:
df -i /path/to/application
If inode use is the limiting resource, identify directories containing unusually large file counts. Mail queues, caches, session storage, and temporary directories can grow in this way. Use methods appropriate for the scale; generating an enormous list in a shell can itself be disruptive.
Review the application’s retention and cleanup policy rather than deleting files based only on age. A queue file or session record may still be in use. Confirm ownership and recovery requirements before removing data.
5. Account for sparse files, links, and filesystem features
A sparse file can have a large apparent size while consuming fewer allocated blocks. Conversely, filesystem metadata and reserved capacity can affect what is available to ordinary users. This is another reason to avoid equating a file listing’s size total with filesystem free space.
Hard links can make several pathnames refer to the same file data. Usage accounting depends on how the tool handles that relationship and how it is invoked. Symbolic links and mounted paths introduce different traversal considerations, so record the options used during comparison.
Snapshots, copy-on-write behavior, compression, quotas, and storage pools can require filesystem-specific tools. A snapshot may retain blocks after visible files are removed. Do not assume that a generic du scan explains every allocation on a platform with advanced storage features.
6. Inspect logs and caches through supported interfaces
Find the largest growing category, then use the owning service’s maintenance mechanism. Journals, container images, package caches, and databases have different retention rules. Deleting internal files directly can corrupt state or bypass important bookkeeping.
For systemd journals, review the configured retention and the evidence you need to preserve before applying cleanup. Our journal retention guide explains how to keep useful records without allowing unchecked growth.
For databases, distinguish ordinary log retention from transaction logs, replication requirements, and backups. A large directory may be necessary for recovery or a lagging replica. Consult the database’s supported maintenance workflow rather than treating it as generic disposable storage.
7. Verify cleanup and prevent recurrence
After an approved change, recheck both filesystem availability and the relevant directory or service state. Confirm the application still works and that space does not immediately grow again. Keep a record of what was removed, reopened, or reconfigured.
Set alerts for the resource that actually failed: free bytes, available inodes, quota, or storage-pool capacity. Choose thresholds based on growth rate and recovery time, not only a percentage. A filesystem with a small percentage free can still have plenty of time at one workload and almost none at another.
Preventive work may include log retention, bounded temporary storage, export cleanup, or increased capacity. Make the owner and expected behavior explicit so the next incident does not require rediscovering the same directory.
Frequently asked questions
Why can df and du show different usage?
They report different views of storage. Deleted open files, inaccessible directories, mount boundaries, filesystem metadata, and advanced storage features can all affect the comparison.
Should I delete the biggest directory first?
No. Identify what owns the data and use a supported cleanup method. Size alone does not tell you whether a database, backup, or application directory is safe to remove.
Where can I verify the command options?
Consult the GNU coreutils manual for df and du on GNU systems. Use your filesystem and platform documentation for snapshots, quotas, compression, and container storage behavior.