Python Disk Usage Monitoring — Core Concepts
Three ways to check disk usage in Python
shutil.disk_usage — the simplest option
import shutil
usage = shutil.disk_usage('/')
print(f"Total: {usage.total / (1024**3):.1f} GB")
print(f"Used: {usage.used / (1024**3):.1f} GB")
print(f"Free: {usage.free / (1024**3):.1f} GB")
print(f"Usage: {usage.used / usage.total * 100:.1f}%")
shutil.disk_usage() is part of Python’s standard library. No extra packages needed. It returns a named tuple with total, used, and free in bytes.
os.statvfs — more detailed filesystem info
import os
stat = os.statvfs('/')
total = stat.f_blocks * stat.f_frsize
free = stat.f_bavail * stat.f_frsize # Available to non-root users
used = total - (stat.f_bfree * stat.f_frsize)
inode_total = stat.f_files
inode_free = stat.f_favail
The key distinction: f_bfree is the total free space (including space reserved for root), while f_bavail is space available to regular users. On most Linux systems, 5% of disk space is reserved for root, so a disk that looks 95% full to a normal user still has space for system operations.
psutil — cross-platform with partition info
import psutil
for partition in psutil.disk_partitions():
try:
usage = psutil.disk_usage(partition.mountpoint)
print(f"{partition.mountpoint}: {usage.percent}% used "
f"({usage.free / (1024**3):.1f} GB free)")
except PermissionError:
continue
psutil also discovers all mounted partitions, giving you a complete picture of every filesystem on the machine.
Building a basic disk monitor
import shutil
from dataclasses import dataclass
@dataclass
class DiskAlert:
path: str
percent_used: float
free_gb: float
level: str # 'warning' or 'critical'
def check_disk_usage(paths: list[str], warn_at=80, critical_at=90) -> list[DiskAlert]:
alerts = []
for path in paths:
usage = shutil.disk_usage(path)
percent = usage.used / usage.total * 100
free_gb = usage.free / (1024**3)
if percent >= critical_at:
alerts.append(DiskAlert(path, percent, free_gb, 'critical'))
elif percent >= warn_at:
alerts.append(DiskAlert(path, percent, free_gb, 'warning'))
return alerts
# Check common paths
alerts = check_disk_usage(['/', '/home', '/var/log', '/tmp'])
for alert in alerts:
print(f"[{alert.level.upper()}] {alert.path}: "
f"{alert.percent_used:.1f}% used, {alert.free_gb:.1f} GB free")
Tracking what is using the space
When a disk is full, the next question is: what is taking up all the space? Python can answer this:
from pathlib import Path
def directory_sizes(root: str, depth: int = 1) -> list[tuple[str, int]]:
"""Get sizes of directories at a given depth."""
root_path = Path(root)
sizes = []
for item in sorted(root_path.iterdir()):
if item.is_dir() and not item.is_symlink():
try:
total = sum(
f.stat().st_size
for f in item.rglob('*')
if f.is_file() and not f.is_symlink()
)
sizes.append((str(item), total))
except PermissionError:
continue
return sorted(sizes, key=lambda x: x[1], reverse=True)
# Find what is eating space in /var
for path, size in directory_sizes('/var')[:10]:
print(f"{size / (1024**3):.2f} GB {path}")
Growth trend detection
A single check tells you the current state. But knowing that a disk is filling up at 2 GB per day — and will be full in 5 days — is far more actionable:
import json
import time
from pathlib import Path
HISTORY_FILE = Path('/var/lib/disk-monitor/history.json')
def record_usage(path: str):
usage = shutil.disk_usage(path)
entry = {
'timestamp': time.time(),
'used_bytes': usage.used,
'total_bytes': usage.total,
}
history = []
if HISTORY_FILE.exists():
history = json.loads(HISTORY_FILE.read_text())
history.append(entry)
# Keep 30 days of hourly samples
history = history[-720:]
HISTORY_FILE.write_text(json.dumps(history))
return history
def predict_days_until_full(history: list[dict]) -> float | None:
if len(history) < 2:
return None
first = history[0]
last = history[-1]
elapsed_days = (last['timestamp'] - first['timestamp']) / 86400
growth_bytes = last['used_bytes'] - first['used_bytes']
if growth_bytes <= 0 or elapsed_days <= 0:
return None # Disk is not growing
growth_per_day = growth_bytes / elapsed_days
remaining_bytes = last['total_bytes'] - last['used_bytes']
return remaining_bytes / growth_per_day
Common misconception
Many people only monitor percentage used. But 90% of a 50 GB disk (5 GB free) is very different from 90% of a 2 TB disk (200 GB free). Always consider both the percentage and the absolute free space. A server with 200 GB free is probably fine even at 90%, while a server with 500 MB free at 75% is in trouble.
Inode exhaustion
Disk space is not the only resource that can run out. Every file and directory uses an inode — a metadata entry in the filesystem. It is possible to have plenty of free space but run out of inodes, especially on systems with millions of small files (like mail servers or caching systems):
import os
stat = os.statvfs('/')
inode_percent = (1 - stat.f_favail / stat.f_files) * 100
print(f"Inode usage: {inode_percent:.1f}%")
Practical use cases
- Server monitoring scripts that check all filesystems and send alerts via email or Slack
- CI/CD pipelines that verify sufficient disk space before starting builds
- Database servers that track data directory growth and predict when storage needs expansion
- Log monitoring that identifies when log directories are growing faster than rotation can clean up
- Backup verification that confirms backup destinations have room for the next scheduled backup
One thing to remember: Effective disk monitoring goes beyond checking a percentage — it tracks growth rates to predict future problems, checks inode usage alongside space, and examines which directories are consuming the most storage to guide cleanup decisions.
See Also
- Python Crontab Management How Python can set up automatic timers on your computer — like programming an alarm clock that runs tasks instead of waking you up.
- Python Log Rotation Management Why your program's diary needs page limits — and how Python keeps log files from eating all your disk space.
- Python Network Interface Monitoring How Python watches your computer's network connections — like having a traffic counter on every road leading to your house.
- Python Process Management How Python lets you see and control all the programs running on your computer — like being the manager of a busy office.
- Python Psutil System Monitoring How Python's psutil library lets your program check on your computer's health — like a doctor with a stethoscope for your machine.