Learn how to check disk space on Linux using df and du, find large files and directories, spot hidden disk usage from deleted but open files, and troubleshoot common out-of-space problems.
Prerequisites
- A Linux server with terminal access
- sudo or root privileges
- Basic familiarity with the Linux command line
What this solves
Running out of disk space is one of the most common causes of failed deployments, crashed databases and broken log pipelines. This tutorial covers how to check disk space usage on Linux with the df and du commands, find large files and directories, and troubleshoot disk space issues that don't match what df reports.
Step-by-step usage
Check overall disk space with df
The df command reports filesystem-level disk space usage. The -h flag prints sizes in human-readable units like GB and MB instead of raw blocks.
df -hTypical output looks like this:
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 38G 10G 80% /
tmpfs 3.9G 0 3.9G 0% /dev/shm
/dev/sdb1 100G 85G 10G 90% /dataFocus on the Use% column. Anything above 85-90% deserves immediate attention, especially on the root filesystem or any partition holding application data.
Show filesystem type and inode usage
Running out of inodes can fill a disk even when there's plenty of free space, because the filesystem runs out of entries to track new files. This commonly happens with applications that create millions of small files, like session caches or mail queues.
df -hTdf -iIf IUse% is near 100% but disk space looks fine, the problem is inode exhaustion, not raw capacity.
Find large directories with du -sh
The du command reports actual disk usage of files and directories, which is what you need to find what's consuming space. The -s flag summarizes, -h makes it human-readable.
sudo du -sh /var/logTo check the size of every top-level directory under /var, run it with a wildcard and summarize each one individually.
sudo du -sh /var/*/ 2>/dev/nullDrill down recursively to find the worst offenders
Start broad and narrow down. This two-step approach is faster than scanning the whole filesystem at once.
sudo du -sh /* 2>/dev/null | sort -rh | head -n 15Once you've identified the heaviest top-level directory, for example /var, repeat the scan one level deeper.
sudo du -sh /var/* 2>/dev/null | sort -rh | head -n 15Keep drilling into the largest result until you reach specific files or log directories.
Find individual large files
Sometimes the problem isn't a directory full of small files but a single huge file, like a core dump, a database snapshot, or an unrotated log.
sudo find / -xdev -type f -size +500M -exec ls -lh {} \; 2>/dev/nullThis searches the current filesystem only (the -xdev flag prevents it from crossing into mounted network shares or other partitions) for files larger than 500MB and prints their size and path.
To sort results by size from largest to smallest:
sudo find / -xdev -type f -size +100M -printf '%s %p\n' 2>/dev/null | sort -rn | head -n 20Combine df and du for full disk space analysis
df tells you which filesystem is full. du tells you what's filling it. Use them together for a complete picture.
df -h /
sudo du -sh /var/log/*.log 2>/dev/null | sort -rh | head -n 10A good troubleshooting workflow is: check df -h to identify which mount point is full, then run du -sh against that specific mount point's subdirectories to locate the cause.
df -h /data
sudo du -sh /data/*/ 2>/dev/null | sort -rh | head -n 10Identify hidden disk usage from deleted but open files
A common and confusing scenario: df shows a disk nearly full, but du can't find anything large enough to explain it. This happens when a process has a file open for writing, and that file gets deleted while the process keeps writing to it. The space isn't released until the process closes the file handle, even though the file no longer appears anywhere in the filesystem tree.
sudo lsof +L1The +L1 flag lists open files with a link count less than 1, meaning the file has been deleted but is still held open by a process. The output shows the process name, PID, and size of the phantom file.
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1842 www-data 3w REG 8,1 4294967296 0 /var/log/nginx/access.log (deleted)To reclaim the space, restart or reload the process holding the file open. For logging daemons this is usually safe and often the correct fix after rotating logs.
sudo systemctl reload nginxIf the owning process can't be restarted immediately, you can sometimes truncate the file in place instead of deleting it, which releases the space without killing the process.
sudo truncate -s 0 /proc/1842/fd/3Sort and filter du output to find space hogs quickly
For large filesystems, combine du with sort and head to immediately see the biggest consumers without scrolling through noise.
sudo du -ah /home/deploy 2>/dev/null | sort -rh | head -n 20The -a flag includes individual files, not just directories, which is useful inside a single user's home directory or application data folder.
To exclude certain paths, like node_modules or vendor directories that you already know are large and expected, use --exclude.
sudo du -sh --exclude=node_modules --exclude=.git /opt/appCommon disk space troubleshooting scenarios
| Scenario | Likely cause | Command to confirm |
|---|---|---|
| df shows 100% used but du can't find large files | Deleted file still held open by a running process | sudo lsof +L1 |
| Disk full but inode usage is low | Genuine large files or directories | sudo du -sh / 2>/dev/null | sort -rh |
| Disk shows free space but writes fail with no space left on device | Inode exhaustion from too many small files | df -i |
| /var/log growing rapidly | Unrotated or verbose application logs | sudo du -sh /var/log/ |
| Docker host runs out of space | Unused images, containers and volumes accumulating | docker system df |
| /tmp fills up unexpectedly | Application temp files not cleaned on crash | sudo du -sh /tmp/* |
For log growth specifically, pairing this with scheduled cleanup is the long-term fix rather than manually clearing space each time. See Configure Linux disk usage monitoring and automated cleanup with systemd timers and Configure Linux log rotation with logrotate and compression for system maintenance for setting up logrotate rules.
If disk pressure is affecting a database, check whether a runaway process is also consuming connections or memory. See Fix PostgreSQL FATAL sorry, too many clients already for a related production incident pattern.
Verify your setup
After cleanup, confirm the disk has actually freed up space, not just that du reports fewer bytes.
df -h
sudo lsof +L1
df -iRe-run df -h and confirm the Use% percentage has dropped on the affected mount point. If it hasn't changed after deleting files, check lsof +L1 again for processes still holding deleted files open.
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| du reports Permission denied for many directories | Running du as a non-root user against system directories | Prefix the command with sudo |
| df shows 100% but deleting files doesn't free space | Deleted file still open by a running process | Run sudo lsof +L1 and restart or reload the owning process |
| du takes a very long time on large filesystems | Scanning millions of small files or network mounts | Use du -sh instead of du -ah, and add -x to stay on one filesystem |
| Disk full error despite df showing free space | Inode exhaustion | Check df -i and clean up directories with excessive small files, like mail queues or PHP sessions |
| Docker host disk fills despite small application footprint | Accumulated unused images, build cache and volumes | Run docker system df then docker system prune with the appropriate flags |
Next steps
- Configure Linux disk usage monitoring and automated cleanup with systemd timers
- Configure Linux log rotation with logrotate and compression for system maintenance
- Set up Linux storage monitoring with smartmontools and automated health alerts
- Configure Linux system monitoring with iostat and disk performance analysis
- Set up RAID arrays with mdadm for performance and redundancy