A full root partition on Linux is more than an annoyance — it can stop packages from installing, break logins, and leave services crashing with “no space left on device.” The good news is that on Ubuntu and most Linux distributions, the space is almost always sitting in a few well-known places: package caches, system logs, old kernels, snap revisions, and per-user caches. This guide walks through how to free up disk space on Ubuntu and other Linux systems safely, in the right order, with a clear note on what’s risky at each step.
First, find out where the space went
Never delete blind. Start by measuring so you’re fixing the real problem, not guessing.
# Overall usage per mounted filesystem
df -h
# Biggest directories under root (needs sudo to read everything)
sudo du -h --max-depth=1 / 2>/dev/null | sort -rh | head -20
# Biggest things in your home folder
du -h --max-depth=1 ~ 2>/dev/null | sort -rh | head -20
df -h tells you which filesystem is full; du tells you what’s in it. For an interactive experience, install ncdu (sudo apt install ncdu) and run ncdu / to walk the tree with live sizes. If you’d rather see your storage as a proportional map instead of a wall of text, GNOME’s Disk Usage Analyzer (Baobab) draws a sunburst chart, and a dedicated analyzer like Declutter gives you a treemap plus a descending size list you can drill into.
The apt package cache
Every package you install with apt leaves its .deb archive in /var/cache/apt/archives/. Over months this grows to gigabytes.
# See how big it is
du -sh /var/cache/apt/archives
# Remove downloaded package files no longer installable
sudo apt clean
# Or remove only the outdated ones, keeping current versions
sudo apt autoclean
Safety: completely safe. These are just cached downloads; apt re-fetches anything it needs. apt clean empties the cache; autoclean is the conservative option.
Orphaned packages and old dependencies
When packages are removed, their automatically-installed dependencies often linger.
sudo apt autoremove --purge
Safety: generally safe, but read the list before confirming. autoremove occasionally proposes removing something you actually use (it keys off what’s marked “automatically installed”). The --purge flag also deletes config files. If a package name looks important, decline and investigate.
Old kernels — handle with care
Ubuntu keeps previous kernel versions so you can boot an older one if a new kernel misbehaves. They live in /boot, which is often a small separate partition, so a few old kernels can fill it and break updates.
# See installed kernels vs. the one you're running
uname -r
dpkg --list | grep linux-image
The safe way to remove old ones is to let apt’s dependency logic do it:
sudo apt autoremove --purge
Safety caveat: never manually rm files from /boot or purge the kernel matching uname -r — that’s your running kernel, and removing it can leave the system unbootable. Always keep the current kernel and at least one known-good previous one. Let apt autoremove decide rather than hand-deleting.
systemd journal logs
journald stores system logs under /var/log/journal and, left unbounded, they can reach several gigabytes.
# Current journal size
journalctl --disk-usage
# Keep only the last 200 MB
sudo journalctl --vacuum-size=200M
# Or keep only the last 2 weeks
sudo journalctl --vacuum-time=2weeks
Safety: safe. You only lose old log history, not any functionality. To cap it permanently, set SystemMaxUse=200M in /etc/systemd/journald.conf.
Snap: old revisions add up fast
Snap keeps multiple revisions of every installed app, and the default is to retain old ones. Each revision is a full copy.
# List revisions, including disabled (old) ones
snap list --all
# Remove disabled revisions
sudo snap remove <name> --revision=<rev>
To automate it and cap retained revisions to the minimum:
sudo snap set system refresh.retain=2
Safety: removing disabled revisions is safe; the active one stays. Don’t remove the current revision of an app you use.
Your user cache: ~/.cache
Applications stash regenerable data in ~/.cache. It can quietly grow to many GB (browsers, thumbnails, package tools).
du -sh ~/.cache/* | sort -rh | head -20
Safety: contents of ~/.cache are, by definition, regenerable — apps recreate what they need. It’s generally safe to clear, but do it while the affected app is closed, and clear specific subfolders rather than nuking the lot if you want to be cautious. Do not confuse ~/.cache with ~/.config (your settings) or ~/.local/share (your actual application data) — those are not caches and should be left alone.
Docker — often the single biggest win for developers
If you use Docker, dangling images, stopped containers, unused volumes, and build cache routinely consume tens of gigabytes.
# See what Docker is using
docker system df
# Remove stopped containers, unused networks, dangling images, build cache
docker system prune
# Also remove *all* unused images and the build cache
docker system prune -a
# Volumes are NOT removed by default — this removes unused ones
docker volume prune
Safety caveat: docker system prune -a removes every image not tied to a running container — you’ll re-pull or rebuild them, which costs time and bandwidth but no data. docker volume prune is the dangerous one: volumes hold persistent data (databases, uploads). Only prune volumes you’re certain nothing needs. There’s a fuller treatment of Docker, package caches, and build artifacts in A Developer’s Guide to Reclaiming Disk Space.
A quick reference table
| Target | Command | Safety | Typical reclaim |
|---|---|---|---|
| apt cache | sudo apt clean | 🟢 Safe | 0.5–3 GB |
| Orphaned deps | sudo apt autoremove --purge | 🟡 Read the list | Varies |
| Old kernels | sudo apt autoremove --purge | 🟡 Keep current + one | 0.3–2 GB |
| journald logs | sudo journalctl --vacuum-size=200M | 🟢 Safe | 0.5–4 GB |
| Snap revisions | snap set system refresh.retain=2 | 🟢 Safe (disabled only) | 1–10 GB |
~/.cache | Clear subfolders while apps closed | 🟢 Regenerable | 1–10 GB |
| Docker | docker system prune -a | 🟡 Re-pull cost | 5–50 GB |
| Docker volumes | docker volume prune | 🔴 Data loss risk | Varies |
The golden rules for Linux cleanup
- Measure first with
df -handdu/ncdu— fix the real offender. - Prefer package-manager commands (
apt clean,autoremove,snap) over hand-deleting files. - Never
rm -rfin system directories —/,/boot,/etc,/usr,/var/lib(package DBs) can brick your system. A stray space inrm -rf /pathis unforgiving. - Keep your running kernel and one fallback.
- Treat Docker volumes and
~/.config/~/.local/shareas data, not clutter. - Clear caches with the app closed so nothing rewrites them mid-delete.
Do it safely with a copilot instead of a footgun
The commands above work, but they demand that you remember which paths are safe and which are landmines. That’s exactly the mistake Declutter is designed to prevent on Linux. It scans your system, then its safety engine surfaces only genuinely reclaimable items — apt/snap and package-manager caches, ~/.cache subtrees, journald logs, Docker layers, trash — with a plain-language “why this is safe” for each. Protected paths like /boot, /etc, /usr, /var/lib/dpkg, and your config and data directories are deny-by-default and can’t be selected. Every deletion is previewed, approved per phase, and moved to a recoverable quarantine first, so undo is always available.
The bottom line
On Ubuntu and Linux, reclaiming space is mostly about knowing the seven or eight places it accumulates and using the package manager’s own cleanup commands rather than a manual rm. Clear the apt cache, vacuum journald, let autoremove retire old kernels, trim snap revisions, prune Docker deliberately, and clear regenerable caches — measure before and after with df -h, and you’ll frequently recover 10–40 GB in a single sitting.
Want the safe version of all this in one app? Try Declutter — it finds Linux clutter, explains why each item is safe, and cleans quarantine-first with full undo. Subscribe to our newsletter for more cross-platform cleanup guides.