When a filesystem fills up, writes fail with No space left on device. Databases stop accepting writes, logging stops, and a service that writes a PID or lock file when it starts can’t be restarted. Work from the outside in: first the filesystem, then the directory, then the files.
Find the full filesystem
df lists every mounted filesystem with its size and use. Leaving out the in-memory ones keeps the list short.
$ df -h -x tmpfs -x devtmpfsFilesystem Size Used Avail Use% Mounted on/dev/sda1 40G 37G 1.0G 98% //dev/sda15 124M 12M 113M 10% /boot/efi/dev/sdb1 200G 61G 130G 32% /var/lib/postgresql
Note the mount point. Everything below / that isn’t on its own filesystem counts against /dev/sda1 here, and /var/lib/postgresql doesn’t.
Check the inodes too
Every file takes an inode, and a filesystem has a fixed number of them. Millions of small files (PHP sessions, a mail queue, a cache directory) can use them all up while df -h still shows free space. The error is the same.
$ df -i /Filesystem Inodes IUsed IFree IUse% Mounted on/dev/sda1 2621440 2621440 0 100% /
If IUse% is the full one, count files instead of bytes to find the directory:
$ sudo du --inodes -x / 2>/dev/null | sort -n | tail -5Find the largest directories
du adds up what each directory holds. -x keeps it on one filesystem, so other mounts and /proc aren’t counted, and sort -h understands the sizes -h prints.
$ sudo du -xh --max-depth=1 / 2>/dev/null | sort -h | tail -684M /etc1.1G /usr2.3G /home2.9G /opt30G /var37G /
Then go one level down into the largest directory, and repeat until the answer is a few files.
$ sudo du -xh --max-depth=1 /var 2>/dev/null | sort -h | tail -4310M /var/cache1.6G /var/lib27G /var/log30G /var
ncdu does the same interactively: you move through the tree with the arrow keys and delete with d. It’s in the Debian and Ubuntu repositories, and in EPEL on RHEL.
$ sudo apt install ncdu$ sudo ncdu -x /
To find single large files anywhere on the filesystem:
$ sudo find / -xdev -type f -size +500M -exec ls -lh {} + 2>/dev/null | sort -k5 -hWhere the space usually is
| Path | What fills it | What to do |
|---|---|---|
/var/log/journal | The systemd journal | Check with journalctl --disk-usage, shrink with --vacuum-size (below) |
/var/log/*.gz | Rotated logs logrotate keeps | Delete old ones; lower rotate in /etc/logrotate.d/ |
/var/cache/apt | Downloaded packages | sudo apt clean (sudo dnf clean all on RHEL) |
/var/lib/docker | Images, stopped containers, build cache | docker system df, then docker system prune |
/tmp | Files left by jobs that crashed | List old ones with find /tmp -mtime +7 |
/home, /root | Dumps and archives made by hand | Ask whoever made them before deleting |
Shrink the journal
By default journald may use up to 10% of the filesystem it’s on, capped at 4 GB. To shrink it to 500 MB:
$ journalctl --disk-usageArchived and active journals take up 3.8G in the file system.$ sudo journalctl --vacuum-size=500M
To keep it there, set the limit in a drop-in file and restart journald:
[Journal]SystemMaxUse=500M
$ sudo systemctl restart systemd-journaldFind space held by deleted files
If du adds up to much less than df reports, a process is probably holding a deleted file open. The usual case is a log file removed with rm while the service still writes to it. The name is gone, so du can’t see it, but the blocks stay allocated until the process closes the file.
$ sudo lsof -nP +L1COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAMEjava 1873 app 12w REG 8,1 9126805504 0 393224 /var/log/app/app.log (deleted)
+L1 lists open files with fewer than one link, which means deleted. Here a Java process holds 9.1 GB. Restart the service to release it, or, if it can’t be restarted, empty the file through the process’s file descriptor (PID 1873, descriptor 12):
$ sudo truncate -s 0 /proc/1873/fd/12Keep it from happening again
- Alert at 80% and 90% use, on bytes and on inodes. A disk rarely fills in one go.
- Give every log a logrotate rule, and journald a
SystemMaxUse. - Put what grows (databases, uploads, Docker) on its own filesystem, so it can’t fill
/. - Clean up after scheduled jobs: a backup that never deletes its old copies fills the disk on a schedule.
Last checked on 24 October 2026 against Debian 12, Ubuntu 24.04, RHEL 9, and GNU coreutils 8.32+. If a step doesn’t match what you see, contact us with the command and what it printed.