# How to find what's using disk space on Linux and free it safely

> Find what filled your server's disk with df, du and ncdu, then safely clean package caches, logs, old kernels and deleted files still held open.

Source: https://vpsnine.com/tutorials/free-up-disk-space-linux · Updated: 2026-10-21

Difficulty: beginner · Time: about 15 minutes · Tested on: Ubuntu 24.04 LTS, AlmaLinux 10

Prerequisites:

- A Linux server
- Root or a user with sudo

To find what's using disk space on Linux, run `df -h` to see which file system is full, then `sudo du -xh --max-depth=1 / | sort -h` to see which top-level folder is big, and repeat `du` one level deeper until you reach the culprit. Most full disks on a server come down to five things: logs, package caches, old kernels, Docker images and backups someone forgot about. Each has a safe way to clean it, below.

The rule that keeps this safe: find out what a file is before you delete it, and never delete anything under `/usr`, `/etc`, `/var/lib` or `/boot` by hand. Use the tool that owns it instead. This tutorial was run on Ubuntu 24.04 and AlmaLinux 10.

## See which disk is full

```bash
df -h
```

Look at **Use%** for `/` (and any other mounted disk). Past about 90%, databases and package upgrades start failing in odd ways; at 100%, services can't write their logs or PID files and may refuse to start.

A disk can also run out of inodes (one per file) while it still has space, typically from millions of tiny cache or session files:

```bash
df -i /
```

If **IUse%** is near 100%, look for the directory with the most files rather than the biggest one; the `du` commands below still point you there.

## Find the biggest folders

Start at the top and walk down. `-x` stays on one file system, so it doesn't wander into `/proc` or other disks:

```bash
sudo du -xh --max-depth=1 / 2>/dev/null | sort -h | tail -n 10
```

The last line is the total; the ones above it are the largest folders. Go one level into the biggest, for example `/var`:

```bash
sudo du -xh --max-depth=1 /var 2>/dev/null | sort -h | tail -n 10
```

Repeat until you find it. On most servers it ends in `/var/log`, `/var/lib/docker`, `/var/cache`, `/home` or a backup directory.

### Or browse it with ncdu

`ncdu` does the same walk interactively: arrow keys to move, Enter to open a folder, `d` to delete, `q` to quit.

```bash
sudo apt install -y ncdu        # Ubuntu, Debian
sudo dnf install -y epel-release && sudo dnf install -y ncdu   # AlmaLinux, Rocky (from EPEL)
sudo ncdu -x /
```

## Find the biggest files

```bash
sudo find / -xdev -type f -size +100M -exec ls -lh {} + 2>/dev/null | awk '{print $5, $9}' | sort -h
```

This lists every file over 100 MB with its size. Typical finds: database dumps, `.tar.gz` backups, a forgotten ISO, a log file that was never rotated.

## Clean the package cache

Package managers keep the files they downloaded. Removing them is always safe; they're downloaded again if needed.

```bash
sudo apt clean                  # Ubuntu, Debian: empties /var/cache/apt/archives
sudo dnf clean all              # AlmaLinux, Rocky, Fedora: empties /var/cache/dnf
```

Then remove packages that were installed as dependencies and are no longer needed, which includes old kernels on Ubuntu and Debian:

```bash
sudo apt autoremove --purge     # Ubuntu, Debian
sudo dnf autoremove             # AlmaLinux, Rocky
```

Read the list before you answer yes. On AlmaLinux and Rocky, old kernels are handled separately: dnf keeps the three newest (`installonly_limit=3` in `/etc/dnf/dnf.conf`) and removes older ones on its own.

On Ubuntu, snap packages keep older revisions too. `snap list --all` shows them marked `disabled`; `sudo snap set system refresh.retain=2` keeps fewer from now on.

## Shrink the logs

The systemd journal is often the biggest single item in `/var/log`:

```bash
journalctl --disk-usage
sudo journalctl --vacuum-size=200M
```

To keep it small for good, set `SystemMaxUse=` as shown in [read logs with journalctl](https://vpsnine.com/tutorials/read-logs-with-journalctl).

Text logs in `/var/log` are rotated and compressed by `logrotate`. Old compressed ones (`*.gz`, `*.1`) can go:

```bash
sudo find /var/log -type f -name '*.gz' -mtime +30 -delete
```

If a single log keeps growing, don't delete it while the program is writing to it (see the next section). Empty it instead:

```bash
sudo truncate -s 0 /var/log/myapp/app.log
```

Then fix the cause: an app logging at debug level, or a log with no `logrotate` rule. The files in `/etc/logrotate.d/` are good examples to copy.

## Deleted files that still take space

If you deleted a big file but `df` doesn't go down, a running program still has it open. The space is only freed when the program closes it. Find those files:

```bash
sudo lsof +L1
```

```text
COMMAND  PID USER   FD   TYPE DEVICE  SIZE/OFF NLINK   NODE NAME
myapp   3665 root    1w   REG  0,141 209715200     0 470591 /var/tmp/big.log (deleted)
```

Restarting that program (`sudo systemctl restart myapp`) frees the space. If you can't restart it now, empty the file through the program's open handle, using the PID and FD from the output (`1w` means descriptor 1):

```bash
sudo truncate -s 0 /proc/3665/fd/1
```

## Docker

Docker keeps old images, stopped containers and build cache in `/var/lib/docker`. Never delete files there by hand. See what it uses, then prune:

```bash
docker system df
docker system prune
```

`prune` removes stopped containers, unused networks, dangling images and build cache. It doesn't touch volumes unless you add `--volumes`, and you shouldn't without checking what's in them: that's where container databases keep their data.

## Troubleshooting

**`No space left on device` but `df -h` shows free space.** Check inodes with `df -i`. If they're full, find the directory with the most files: `sudo du -x --inodes --max-depth=1 / | sort -n | tail`.

**`df` and `du` disagree by a lot.** Deleted files that are still open (above), or files hidden under a mount point. `sudo lsof +L1` covers the first.

**`apt` or `dnf` fails because there's no room to download packages.** Run `sudo apt clean` or `sudo dnf clean all` first; neither needs free space to work.

**The disk fills again within days.** Something writes continuously. `sudo du -xh --max-depth=2 /var | sort -h | tail` today and again tomorrow shows which folder grows.

## Next steps

- Keep the journal capped: [read logs with journalctl](https://vpsnine.com/tutorials/read-logs-with-journalctl).
- Watch disk use over time: [monitor your server](https://vpsnine.com/help/monitor-your-server).
- If the server is slow rather than full: [troubleshoot high CPU and memory](https://vpsnine.com/tutorials/troubleshoot-high-cpu-and-memory).

## Doing it on VPSNine

On VPSNine, take a [snapshot](https://vpsnine.com/help/snapshots) before a big clean-up so you can undo it. If you keep running out of room, the larger [plans](https://vpsnine.com/plans) have more NVMe disk (40, 80 and 160 GB). When a server is so full it won't boot, [rescue mode](https://vpsnine.com/help/rescue-mode) mounts its disk so you can clear space from outside. Works the same on [Ubuntu 24.04](https://vpsnine.com/os/ubuntu-24.04) and [AlmaLinux 10](https://vpsnine.com/os/almalinux-10).
