If you work with Linux servers long enough, sooner or later you'll see this:
df -h
and discover that your disk is 95% full.
The next question is:
What is using all that space?
This is where two Linux commands become essential:
df → How full is my filesystem?
du → What is using the space?
Once you understand this distinction, disk-space troubleshooting becomes much easier.
1. df: How Full Is My Filesystem?
df stands for disk free.
It reports disk-space information at the filesystem level.
Start with:
df
You'll get something like:
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/nvme0n1p2 104857600 62914560 41943040 60% /
The numbers aren't particularly convenient to read, so we normally use -h.
df -h
df -h
Example:
Filesystem Size Used Avail Use% Mounted on
/dev/nvme0n1p2 100G 60G 35G 64% /
/dev/nvme0n1p1 512M 10M 502M 2% /boot/efi
The -h means human-readable. Instead of large numbers, Linux shows sizes such as:
512M
10G
100G
1.2T
Understanding the output
Consider:
Filesystem Size Used Avail Use% Mounted on
/dev/nvme0n1p2 100G 60G 35G 64% /
- Filesystem → the filesystem/device
- Size → total capacity
- Used → space currently used
- Avail → available space
- Use% → percentage used
- Mounted on → where the filesystem is mounted
So this tells us:
The filesystem mounted at
/has 100 GB of capacity, 60 GB is used, and it is 64% full.
But df doesn't tell us what is using those 60 GB.
That's where du comes in.
2. du: Where Is the Space Being Used?
du stands for disk usage.
While df works at the filesystem level, du works with files and directories.
It answers:
How much space are these files and directories using?
Try:
du
You'll get output showing directory usage.
Again, we usually want human-readable values:
du -h
For example:
4.0K ./config
120M ./data
1.2G ./node_modules
1.4G .
3. du -sh: Get the Total
Suppose you want to know how much space /var is using.
du -sh /var
Example:
12G /var
There are two options here:
-s → summary
-h → human-readable
So:
du -sh /var
means:
Give me a human-readable summary of the disk usage of
/var.
4. du -sh *: See the Size of Everything Here
One of the most useful commands is:
du -sh *
Suppose your current directory contains:
config/
data/
logs/
node_modules/
You might get:
4.0K config
120M data
20M logs
1.2G node_modules
Now it's immediately obvious that node_modules is the largest directory.
The * is a shell wildcard meaning:
The items in the current directory.
The shell expands the command before du receives it.
Conceptually:
du -sh *
becomes something like:
du -sh config data logs node_modules
5. du --max-depth
Sometimes you don't want du to recursively show everything.
You only want to see the first level of directories.
Use:
du -h --max-depth=1
Example:
120M ./data
20M ./logs
1.2G ./node_modules
1.4G .
This is extremely useful for investigating a large directory.
For example:
sudo du -h --max-depth=1 /var
might show:
45G /var/lib
20G /var/log
8G /var/cache
80G /var
Now you know that /var/lib is the directory worth investigating.
You can go one level deeper:
sudo du -h --max-depth=1 /var/lib
Maybe you'll find:
30G /var/lib/docker
10G /var/lib/postgresql
5G /var/lib/apt
You can keep drilling down until you find the source.
6. Sort du by Size
du doesn't automatically sort the results.
Combine it with sort:
du -h --max-depth=1 | sort -h
For largest first:
du -h --max-depth=1 | sort -hr
Here:
-h → understand human-readable sizes
-r → reverse the order
So:
du -h --max-depth=1 | sort -hr
might produce:
1.4G .
1.2G ./node_modules
120M ./data
20M ./logs
4.0K ./config
This is one of the commands I use most when investigating disk usage.
7. df and du Together
This is the most important part.
Imagine you run:
df -h
and get:
Filesystem Size Used Avail Use% Mounted on
/dev/nvme0n1p2 100G 90G 5G 95% /
You now know:
My root filesystem is almost full.
But you don't know why.
So you run:
sudo du -h --max-depth=1 / | sort -hr
and discover:
90G /
50G /var
25G /home
10G /usr
Now you know:
/varis consuming 50 GB.
So investigate /var:
sudo du -h --max-depth=1 /var | sort -hr
You might find:
50G /var
35G /var/lib
10G /var/log
5G /var/cache
Then:
sudo du -h --max-depth=1 /var/lib | sort -hr
And continue until you find the actual source.
The workflow is:
df -h
↓
"Filesystem is almost full"
↓
du /
↓
"Which directory is consuming the space?"
↓
du /large-directory
↓
"Which subdirectory?"
↓
keep drilling down
8. The Difference Between df and du
This distinction is worth memorizing.
| Command | Answers |
|---|---|
df |
How full is the filesystem? |
du |
What is using the space? |
Think of it like this:
Disk
│
┌───────┴───────┐
│ │
df du
│ │
▼ ▼
Filesystem level File/directory level
│ │
▼ ▼
"90 GB is used" "50 GB is in /var"
Or simply:
dftells you that you have a problem.duhelps you find the problem.
9. Why df and du Can Sometimes Disagree
You might encounter something strange:
df -h
says:
100G total
90G used
but:
sudo du -sh /
only reports:
70G
Where did the other 20 GB go?
One common explanation is deleted files that are still open by a process.
Consider this:
Process
│
└── opens huge.log
│
▼
20 GB
Then someone deletes the file:
rm huge.log
The filename disappears from the filesystem, so du can no longer see it.
But the process still has the file open.
Therefore:
du → doesn't count it
df → still counts the space
You can investigate deleted-but-open files with:
sudo lsof +L1
This is one reason df and du are not interchangeable.
10. df -T: See the Filesystem Type
You can also ask df to show the filesystem type:
df -Th
Example:
Filesystem Type Size Used Avail Use% Mounted on
/dev/nvme0n1p2 ext4 100G 60G 35G 64% /
The -T adds the filesystem type.
For example:
ext4
xfs
btrfs
11. A Real Example: Investigating APT
Suppose you notice that:
sudo du -sh /var/lib/apt/*
returns:
4.0K /var/lib/apt/cdroms.list
152K /var/lib/apt/extended_states
400M /var/lib/apt/lists
8.0K /var/lib/apt/mirrors
4.0K /var/lib/apt/periodic
Immediately, you can see:
/var/lib/apt/lists → 400M
is the major consumer.
You can investigate further:
sudo du -sh /var/lib/apt/lists/*
This is the real power of du: you can drill down through the filesystem until you find what is consuming the space.
12. Why Docker Deletes /var/lib/apt/lists/*
You may have seen this Dockerfile:
RUN apt-get update \
&& apt-get install -y --no-install-recommends libgdal-dev \
&& rm -rf /var/lib/apt/lists/*
apt-get update downloads package indexes into:
/var/lib/apt/lists/
These indexes are needed by APT to find packages, but after the package installation they usually aren't needed by the application.
Therefore:
rm -rf /var/lib/apt/lists/*
removes them and makes the Docker image smaller.
You can see how much space they consume with:
sudo du -sh /var/lib/apt/lists
13. The Commands Worth Memorizing
You don't need to memorize every option.
For df:
df -h
Show filesystem usage in human-readable form.
df -Th
Show filesystem usage and filesystem type.
For du:
du -sh /var
Show the total size of
/var.
du -sh *
Show the size of every item in the current directory.
du -h --max-depth=1
Show directory sizes one level deep.
du -h --max-depth=1 | sort -hr
Show directory sizes one level deep, largest first.
And for serious disk investigation:
sudo du -h --max-depth=1 / | sort -hr
14. A Practical Disk-Space Troubleshooting Workflow
When someone tells you:
"The server is running out of disk space."
Start here:
df -h
Find the filesystem that is almost full.
Then:
sudo du -h --max-depth=1 / | sort -hr
Find the largest directory.
Then investigate that directory:
sudo du -h --max-depth=1 /var | sort -hr
Then continue:
sudo du -h --max-depth=1 /var/lib | sort -hr
And so on.
For example:
df -h
↓
/ is 95% full
↓
du /
↓
/var is 60 GB
↓
du /var
↓
/var/lib is 50 GB
↓
du /var/lib
↓
/var/lib/docker is 45 GB
↓
investigate Docker
This is a skill you'll use constantly when working with Linux servers, Docker, Kubernetes nodes, databases, and CI/CD systems.
15. Final Mental Model
Don't think of du and df as two commands that do the same thing.
Think:
DISK SPACE
│
┌───────────┴───────────┐
│ │
df du
│ │
▼ ▼
Filesystem level File/directory level
│ │
▼ ▼
"How full is it?" "What's using it?"
When troubleshooting disk usage:
df -h
first.
Then:
sudo du -h --max-depth=1 / | sort -hr
second.
That's the fundamental Linux disk-usage workflow:
dftells you how full the filesystem is.dutells you where the space is being used.
Top comments (0)