Skip to main content

whyfull

Find out why your Linux disk is full, and get the command that fixes it.

CI PyPI Python 3.6+ License: MIT

df says 100%. du doesn't add up. Something is failing with No space left on device.

whyfull checks the places where disk space usually goes on a Linux server: deleted files that a process still holds open, the systemd journal, Docker images and container logs, old kernels, package caches, core dumps, runaway logs and inode exhaustion. For each thing it finds, it prints how much space it takes, how risky it is to remove, and the exact command to get the space back.

It never deletes anything itself.

Prefer to fix it by hand? The guides walk through each cause: df vs du, deleted files still using space, Docker, the systemd journal, inodes, /var/log and old kernels.

whyfull showing a full root filesystem: a 700 MB deleted nginx log still held open, a 560 MB Docker container log, unused images, old kernels and the systemd journal, each with the command that frees it

Run it

A full disk may leave no room to install anything, so whyfull is a single 35 KB file with no dependencies. It runs on the Python 3 that already ships with nearly every Linux server (3.6 or newer). Download it to /dev/shm, which lives in memory:

curl -fsSL -o /dev/shm/whyfull https://github.com/amlaban65/whyfull/releases/latest/download/whyfull.pyz
sudo python3 /dev/shm/whyfull

Or install it from PyPI:

pipx install whyfull      # or: uv tool install whyfull, pip install --user whyfull
sudo "$(command -v whyfull)"

uvx whyfull and pipx run whyfull work for a one-off run.

Run it with sudo. Without root it can't measure files owned by other users and services, and it will tell you what it couldn't read.

What it looks for

Check What it finds
deleted-open Files that were deleted while a process still had them open. This is the classic "df says full but du says otherwise". whyfull names the systemd service or Docker container holding them and shows how to release the space with or without a restart.
docker Build cache, unused images, stopped containers, dangling volumes, and container logs with no size limit.
cri Unused containerd/CRI-O images reported by crictl; running and stopped container references are preserved. Shared layers can reduce the actual reclaimed space.
podman Reclaimable rootful Podman images and stopped containers outside CRI-O nodes. Rootless stores are measured from disk and labeled informational; no other user's Podman commands are run.
journald A systemd journal that has grown past a sensible size, with the commands to vacuum it and cap it.
logs Rotated and compressed logs in /var/log, and single log files over 1 GB.
pod-logs The largest kubelet pod log directories, with rotation settings and explicitly cautious truncation commands.
kernels Installed kernels other than the running one and the newest one, with the right removal command for apt, dnf or zypper.
packages apt, dnf, yum, pacman, zypper and apk caches.
snaps Disabled snap revisions that snapd keeps around.
crashes Core dumps from systemd-coredump, apport and ABRT, and /var/crash.
tmp Files in /tmp and /var/tmp nobody has touched in a week.
user-caches pip, uv, poetry, npm, yarn, pnpm, Go, Cargo, Maven, Gradle, Hugging Face, PyTorch and conda caches, and the Trash, for every user.
android Per-user emulator data and SDK system images, with Android tooling commands for reviewing and removing selected items.
mysql MySQL and MariaDB binary logs in /var/lib/mysql, with the PURGE BINARY LOGS and binlog_expire_logs_seconds fixes.
inodes A filesystem that ran out of inodes (too many files) rather than bytes, and the directories with the most entries.
reserved ext filesystems that look full only because of the 5% reserved for root.

whyfull also scans the whole filesystem (with a time limit) and lists the largest directories. When the files it can see add up to much less than df reports, it says so, and points to where the rest usually is. Common causes are files hidden underneath a mount point and btrfs or ZFS snapshots.

whyfull --list-checks prints the list from your installed version.

Risk levels

Every finding is labelled so you know what you're agreeing to:

  • safe: caches that are rebuilt on demand. Removing them costs a slower next build or download.
  • review: almost always fine to remove (old kernels, rotated logs, unused images), but take a look first.
  • caution: can lose data or affect a running service, such as truncating a live log or pruning Docker volumes.
  • info: explains what's going on, like inode exhaustion or the root reserve, without a direct cleanup.

Usage

sudo whyfull                      # every filesystem that is 85% full or more
sudo whyfull /var                 # only the filesystem holding /var
sudo whyfull -t 70                # lower the "full" threshold to 70%
sudo whyfull -v                   # explain every finding, list all evidence
sudo whyfull --no-scan            # skip the full scan, run only the checks
sudo whyfull --exclude /var/lib/db --exclude /media  # skip known paths in the full scan
sudo whyfull --only docker,logs   # run some checks; see --list-checks

--exclude PATH is repeatable and only affects the full scan. Excluded files and directories are omitted from scan totals and largest-directory listings; targeted checks still inspect them. When exclusions are set, whyfull skips the unexplained-space finding and adds a report note, since comparing a partial scan with df would otherwise make excluded data look like missing space.

If nothing is above the threshold, whyfull analyses / anyway and tells you the disks are fine.

For incident tickets, scripts and monitoring

sudo whyfull --format markdown > disk.md   # paste into a ticket or chat
sudo whyfull --json | jq '.targets[].findings[] | {title, bytes, risk}'
whyfull --fail-above 90 --no-scan          # exits 1 when any filesystem is 90%+ full

Exit codes: 0 when the run finished, 1 when --fail-above was exceeded, 2 for usage errors.

How is this different from ncdu, du, dust or gdu?

Those are great for browsing a directory tree, and you should keep using them. They answer "which folder is big". whyfull answers "what is this space, and how do I get it back without breaking anything". It finds space that no directory browser can see (deleted files held open by a process). It knows that /var/lib/docker/overlay2 is cleaned with docker image prune, not rm. It knows which kernels are safe to remove, and that a 2 GB syslog.2.gz can go while a live syslog should be truncated.

Run whyfull first. If something is still unexplained, open ncdu on the directory it points to.

Safety

  • whyfull only reads. It does not delete, truncate, prune or restart anything.
  • The only commands it runs are read-only: docker system df, docker info, crictl images, crictl ps -a, podman system df and snap list --all.
  • Every fix is printed for you to read and run yourself. Commands that can lose data are marked caution and explained.
  • Scans stay on one filesystem (like du -x), count hard links once, and stop at a time limit, so they won't hang on a huge disk or wander into network mounts.

Contributing

The most useful contribution is a new check: "my disk filled up because of X, and here is how to spot it and clean it up." Each check is one short file in src/whyfull/checks/, and tests run against a fake filesystem, so you don't need a full disk to write one. CONTRIBUTING.md walks through it.

Some checks that would help a lot of people: PostgreSQL WAL, Elasticsearch, Prometheus, LXD, Flatpak, Jenkins workspaces, libvirt disk images, CI runner work directories, and btrfs or ZFS snapshots. The open issues describe several of them in detail. If you have a war story about a disk that filled up in a strange way, open an issue even if you don't plan to write the code.

License

MIT

Metadata

Release files for whyfull 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for whyfull 0.2.0
File Size Uploaded Provenance Actions
whyfull-0.2.0.tar.gz 45.1 kB With provenance Details for whyfull-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for whyfull 0.2.0
File Interpreter ABI Platform Actions
whyfull-0.2.0-py3-none-any.whl Python 3 none any Details for whyfull-0.2.0-py3-none-any.whl

Total release size: 87.8 kB

Release files / whyfull-0.2.0.tar.gz

Download URL whyfull-0.2.0.tar.gz
Size 45.1 kB
Tags Source
SHA-256 checksum
How to use checksums
2d1657e56f437f969963096906c9cb3128e826161347f8e34132e63afd73ffc2
BLAKE2b-256 checksum
How to use checksums
efc7f7c211e43021ebce85636960b8f211fefb942bdc01fd8e6d132acffe7d1f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / whyfull-0.2.0-py3-none-any.whl

Download URL whyfull-0.2.0-py3-none-any.whl
Size 42.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b7845d51495006f5d1a5deccca705c7bcfd6ee10257c089d29c4e853a4021756
BLAKE2b-256 checksum
How to use checksums
85419848778084ee0e7b5bd8313e85255534cdbd43c6cc471cf934a2dad020d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Security for whyfull 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for whyfull-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page