Linux

Find what’s filling a disk

A full filesystem stops writes, logs, and often the service on top of it. Find which filesystem is full, which directory holds the space, and which deleted files a process is still holding open.

Written againstDebian 12Ubuntu 24.04RHEL 9GNU coreutils 8.32+
Reading time
4 min
Commands to copy
13
Last checked
24 Oct 2026

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.

shell
$ 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.

shell
$ 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:

shell
$ sudo du --inodes -x / 2>/dev/null | sort -n | tail -5

Find 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.

shell
$ 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.

shell
$ 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.

shell
$ sudo apt install ncdu$ sudo ncdu -x /

To find single large files anywhere on the filesystem:

shell
$ sudo find / -xdev -type f -size +500M -exec ls -lh {} + 2>/dev/null | sort -k5 -h

Where the space usually is

PathWhat fills itWhat to do
/var/log/journalThe systemd journalCheck with journalctl --disk-usage, shrink with --vacuum-size (below)
/var/log/*.gzRotated logs logrotate keepsDelete old ones; lower rotate in /etc/logrotate.d/
/var/cache/aptDownloaded packagessudo apt clean (sudo dnf clean all on RHEL)
/var/lib/dockerImages, stopped containers, build cachedocker system df, then docker system prune
/tmpFiles left by jobs that crashedList old ones with find /tmp -mtime +7
/home, /rootDumps and archives made by handAsk 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:

shell
$ 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:

/etc/systemd/journald.conf.d/size.conf
[Journal]SystemMaxUse=500M
shell
$ sudo systemctl restart systemd-journald

Find 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.

shell
$ 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):

shell
$ sudo truncate -s 0 /proc/1873/fd/12

Keep 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.