Disk Space and Inode Usage Monitoring: Complete System Administrator's Guide

Proactive monitoring of disk space and inode usage is fundamental to maintaining healthy Linux systems. Running out of disk space or exhausting inodes can cause system failures, application crashes, and data loss. Understanding how to monitor, analyze, and automate disk usage monitoring prevents these critical issues before they impact production systems.

This comprehensive guide covers all aspects of disk space and inode monitoring, from basic commands to advanced automated monitoring solutions with alerting.

Introduction to Disk Space and Inode Monitoring

Disk usage monitoring involves tracking two critical resources:

  1. Disk Space: The amount of storage consumed by files and directories
  2. Inodes: The number of filesystem objects (files, directories, links)

Both resources are finite and can be exhausted independently. A filesystem can run out of space or inodes, either condition preventing new file creation.

Why Monitor Disk Usage?

  • Prevent system failures: Full disks cause application crashes and system instability
  • Avoid data loss: Insufficient space prevents logging and data writes
  • Maintain performance: Full filesystems degrade performance
  • Capacity planning: Usage trends inform infrastructure decisions
  • Cost optimization: Identify storage waste in cloud environments
  • Compliance: Meet retention and storage policies
  • Troubleshooting: Quickly identify space-consuming processes

Common Disk Space Issues

  • Log files: Unrotated logs filling filesystems
  • Temporary files: Accumulated temp files not cleaned up
  • Database growth: Expanding databases without monitoring
  • User data: Uncontrolled user file uploads
  • Backup files: Old backups not deleted
  • Core dumps: Large core dumps from crashed processes
  • Inode exhaustion: Millions of small files consuming all inodes

Prerequisites

To effectively monitor disk usage, you need:

  • Basic understanding of Linux filesystem concepts
  • Access to the system (user or root depending on monitored locations)
  • Knowledge of filesystem types in use
  • Understanding of normal usage patterns
  • Familiarity with cron for automation
  • Basic scripting knowledge for custom monitoring

Basic Disk Space Monitoring Commands

Using df: Disk Free Space

The df command shows filesystem disk space usage.

Basic Usage

df -h

Output:

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        50G   35G   13G  74% /
/dev/sda2       100G   60G   35G  63% /home
/dev/sdb1       500G  450G   26G  95% /mnt/data
tmpfs           7.8G  1.2M  7.8G   1% /dev/shm

Common df Options

# Human-readable output
df -h

# Include filesystem type
df -hT

# Show inodes instead of blocks
df -hi

# Include all filesystems (including pseudo-filesystems)
df -ha

# Exclude specific filesystem types
df -h -x tmpfs -x devtmpfs

# Show specific filesystem
df -h /home

Understanding df Output

  • Filesystem: Device or virtual filesystem
  • Size: Total capacity
  • Used: Space consumed
  • Avail: Available space
  • Use%: Percentage used
  • Mounted on: Mount point

Using du: Disk Usage

The du command shows disk usage of files and directories.

Basic Usage

# Show directory size
du -sh /var/log

# Show all subdirectories
du -h /var/log

# Limit depth
du -h --max-depth=1 /var

Find Large Directories

# Top 10 largest directories in /var
du -h /var | sort -rh | head -10

# Show sizes for all immediate subdirectories
du -h --max-depth=1 /var | sort -rh

# Find directories larger than 1GB
du -h /var | awk '$1 ~ /^[0-9.]+G/ {print $0}'

Find Large Files

# Find files larger than 100MB in /var
find /var -type f -size +100M -exec du -h {} + | sort -rh

# Top 20 largest files in home directories
find /home -type f -exec du -h {} + | sort -rh | head -20

# Find files larger than 1GB anywhere
sudo find / -type f -size +1G -exec ls -lh {} \; 2>/dev/null

Analyze Specific Directory

# Detailed analysis of /var/log
du -h /var/log | sort -rh | head -20

# With file count
du -sh /var/log/* | sort -rh

Inode Monitoring

Understanding Inodes

Each file and directory consumes one inode. Running out of inodes prevents file creation even with available disk space.

Check Inode Usage

# Show inode usage
df -hi

# Show inode usage for specific filesystem
df -hi /home

Output:

Filesystem     Inodes IUsed IFree IUse% Mounted on
/dev/sda1        3.2M   500K  2.7M   16% /
/dev/sda2        6.5M   2.5M  4.0M   39% /home
/dev/sdb1         32M    25M  6.8M   79% /mnt/data

Find Directories with Many Files

# Count files in directories
for dir in /var/*; do
    echo -n "$dir: "
    find "$dir" -type f | wc -l
done

# Find directories with most files
find /var -type d -exec sh -c 'echo -n "{}: "; find "{}" -maxdepth 1 -type f | wc -l' \; | sort -t: -k2 -rn | head -10

# Count files in immediate subdirectories
for dir in /var/log/*; do
    count=$(find "$dir" -type f 2>/dev/null | wc -l)
    echo "$count $dir"
done | sort -rn

Find File Systems with Many Small Files

# Average file size per filesystem
df -h | awk 'NR>1 {print $6}' | while read mount; do
    total_size=$(du -sb "$mount" 2>/dev/null | awk '{print $1}')
    file_count=$(find "$mount" -type f 2>/dev/null | wc -l)
    if [ "$file_count" -gt 0 ]; then
        avg_size=$((total_size / file_count))
        echo "$mount: $file_count files, avg size: $(( avg_size / 1024 ))KB"
    fi
done

Real-Time Monitoring

Watch Disk Space in Real-Time

# Update every 2 seconds
watch -n 2 'df -h'

# Monitor specific filesystem
watch -n 2 'df -h /var/log'

# Monitor with inode information
watch -n 2 'df -h && echo && df -hi'

Monitor Disk Usage Changes

# Monitor directory size changes
watch -n 5 'du -sh /var/log'

# Track fastest growing directory
watch -n 10 'du -h --max-depth=1 /var | sort -rh | head -5'

Monitor File Creation Rate

# Count files created in last minute
watch -n 60 'find /tmp -type f -mmin -1 | wc -l'

Automated Monitoring Scripts

Basic Disk Space Monitoring Script

sudo nano /usr/local/bin/disk_monitor.sh
#!/bin/bash

# Disk Space Monitoring Script
THRESHOLD=80
EMAIL="[email protected]"
LOGFILE="/var/log/disk_monitor.log"

# Check each filesystem
df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $6 }' | while read output;
do
    usage=$(echo $output | awk '{print $1}' | sed 's/%//g')
    partition=$(echo $output | awk '{print $2}')

    if [ $usage -ge $THRESHOLD ]; then
        timestamp=$(date '+%Y-%m-%d %H:%M:%S')
        message="$timestamp - WARNING: Disk usage on $partition is at ${usage}%"
        echo "$message" >> $LOGFILE

        # Send email alert (requires mail command)
        echo "$message" | mail -s "Disk Space Alert: $partition" $EMAIL
    fi
done

Make executable:

sudo chmod +x /usr/local/bin/disk_monitor.sh

Schedule with cron:

# Run every hour
echo "0 * * * * /usr/local/bin/disk_monitor.sh" | sudo crontab -

Advanced Monitoring Script with Inode Check

sudo nano /usr/local/bin/disk_inode_monitor.sh
#!/bin/bash

# Disk Space and Inode Monitoring Script
DISK_THRESHOLD=80
INODE_THRESHOLD=80
EMAIL="[email protected]"
LOGFILE="/var/log/disk_inode_monitor.log"

timestamp=$(date '+%Y-%m-%d %H:%M:%S')

# Check disk space
echo "[$timestamp] Disk Space Check" >> $LOGFILE
df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $6 }' | while read output;
do
    usage=$(echo $output | awk '{print $1}' | sed 's/%//g')
    partition=$(echo $output | awk '{print $2}')

    if [ $usage -ge $DISK_THRESHOLD ]; then
        alert="WARNING: Disk usage on $partition is at ${usage}%"
        echo "$alert" >> $LOGFILE
        echo "$alert" | mail -s "Disk Space Alert: $partition" $EMAIL
    fi
done

# Check inode usage
echo "[$timestamp] Inode Usage Check" >> $LOGFILE
df -i | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $6 }' | while read output;
do
    usage=$(echo $output | awk '{print $1}' | sed 's/%//g')
    partition=$(echo $output | awk '{print $2}')

    if [ $usage -ge $INODE_THRESHOLD ]; then
        alert="WARNING: Inode usage on $partition is at ${usage}%"
        echo "$alert" >> $LOGFILE
        echo "$alert" | mail -s "Inode Alert: $partition" $EMAIL
    fi
done

Growth Tracking Script

sudo nano /usr/local/bin/disk_growth_tracker.sh
#!/bin/bash

# Disk Growth Tracking Script
DATAFILE="/var/log/disk_growth.log"
REPORTFILE="/var/log/disk_growth_report.txt"

# Record current usage
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
df -BG | grep -vE '^Filesystem|tmpfs' | awk -v ts="$timestamp" '{print ts "," $6 "," $3}' >> $DATAFILE

# Generate weekly growth report (run on Sundays)
if [ $(date +%u) -eq 7 ]; then
    {
        echo "Weekly Disk Growth Report"
        echo "Generated: $(date)"
        echo "================================"
        echo ""

        # Calculate growth for each filesystem
        for mount in $(df | grep -vE '^Filesystem|tmpfs' | awk '{print $6}'); do
            echo "Filesystem: $mount"

            # Get data from last 7 days
            week_ago=$(date -d '7 days ago' '+%Y-%m-%d')
            current=$(grep "$mount" $DATAFILE | tail -1 | cut -d',' -f3)
            previous=$(grep "$mount" $DATAFILE | grep "$week_ago" | tail -1 | cut -d',' -f3)

            if [ -n "$current" ] && [ -n "$previous" ]; then
                growth=$((${current%G} - ${previous%G}))
                echo "  Growth: ${growth}GB in 7 days"
            fi
            echo ""
        done
    } > $REPORTFILE

    # Email report
    mail -s "Weekly Disk Growth Report" [email protected] < $REPORTFILE
fi

Directory Size Monitoring Script

sudo nano /usr/local/bin/directory_size_monitor.sh
#!/bin/bash

# Monitor specific directories for size changes
MONITORED_DIRS="/var/log /home /var/lib/mysql"
THRESHOLD_GB=10
LOGFILE="/var/log/directory_size_monitor.log"

for dir in $MONITORED_DIRS; do
    if [ -d "$dir" ]; then
        size=$(du -sb "$dir" 2>/dev/null | awk '{print $1}')
        size_gb=$((size / 1024 / 1024 / 1024))

        timestamp=$(date '+%Y-%m-%d %H:%M:%S')
        echo "$timestamp - $dir: ${size_gb}GB" >> $LOGFILE

        if [ $size_gb -ge $THRESHOLD_GB ]; then
            message="$dir has reached ${size_gb}GB"
            echo "$message" | mail -s "Directory Size Alert" [email protected]
        fi
    fi
done

Disk Space Analysis Tools

Using ncdu (NCurses Disk Usage)

Interactive disk usage analyzer.

Install:

# Debian/Ubuntu
sudo apt install ncdu

# CentOS/RHEL
sudo yum install ncdu

Usage:

# Analyze directory
ncdu /var

# Analyze with one filesystem
ncdu -x /var

# Export to file
ncdu -o /tmp/var_usage.txt /var

# Import from file
ncdu -f /tmp/var_usage.txt

Using agedu (Age-Based Disk Usage)

Find old, large files.

Install:

sudo apt install agedu

Usage:

# Index directory
agedu -s /home

# Generate report of files unused in 6 months
agedu -a /home -t 180d

# Web interface
agedu -w --address 0.0.0.0:8000
# Access at http://localhost:8000

Using baobab (GUI Tool)

Graphical disk usage analyzer.

Install:

sudo apt install baobab

Usage:

# Launch GUI
baobab /var

Cleaning Up Disk Space

Safe Cleanup Procedures

Clean Package Manager Cache

# Debian/Ubuntu
sudo apt clean
sudo apt autoclean
sudo apt autoremove

# CentOS/RHEL
sudo yum clean all
sudo dnf clean all

Clean Journald Logs

# Keep only last 7 days
sudo journalctl --vacuum-time=7d

# Keep only 500MB
sudo journalctl --vacuum-size=500M

# Verify space freed
du -sh /var/log/journal

Rotate and Compress Logs

# Force log rotation
sudo logrotate -f /etc/logrotate.conf

# Clean old compressed logs
sudo find /var/log -type f -name "*.gz" -mtime +30 -delete
sudo find /var/log -type f -name "*.old" -mtime +30 -delete

Clean Temporary Files

# Clean /tmp (files older than 10 days)
sudo find /tmp -type f -atime +10 -delete

# Clean /var/tmp
sudo find /var/tmp -type f -atime +30 -delete

# Clean systemd temporary files
sudo systemctl clean --what=cache --all

Clean User Caches

# Clean user cache directories
find ~/.cache -type f -atime +30 -delete

# Clean browser caches (when logged in as user)
rm -rf ~/.cache/mozilla
rm -rf ~/.cache/google-chrome
rm -rf ~/.cache/chromium

Find and Remove Core Dumps

# Find core dumps
sudo find / -name "core.*" -type f 2>/dev/null

# Remove core dumps
sudo find / -name "core.*" -type f -delete 2>/dev/null

# Disable core dumps
echo "* hard core 0" | sudo tee -a /etc/security/limits.conf

Automated Cleanup Script

sudo nano /usr/local/bin/disk_cleanup.sh
#!/bin/bash

# Automated Disk Cleanup Script
LOGFILE="/var/log/disk_cleanup.log"
timestamp=$(date '+%Y-%m-%d %H:%M:%S')

echo "[$timestamp] Starting cleanup" >> $LOGFILE

# Package cache
echo "Cleaning package cache..." >> $LOGFILE
apt clean 2>&1 | tee -a $LOGFILE

# Old kernels (Debian/Ubuntu)
echo "Removing old kernels..." >> $LOGFILE
apt autoremove -y 2>&1 | tee -a $LOGFILE

# Journal logs (keep 7 days)
echo "Cleaning journal logs..." >> $LOGFILE
journalctl --vacuum-time=7d 2>&1 | tee -a $LOGFILE

# Temporary files
echo "Cleaning temporary files..." >> $LOGFILE
find /tmp -type f -atime +7 -delete 2>&1 | tee -a $LOGFILE
find /var/tmp -type f -atime +30 -delete 2>&1 | tee -a $LOGFILE

# Rotate logs
echo "Rotating logs..." >> $LOGFILE
logrotate -f /etc/logrotate.conf 2>&1 | tee -a $LOGFILE

# Old compressed logs
echo "Removing old compressed logs..." >> $LOGFILE
find /var/log -name "*.gz" -mtime +60 -delete 2>&1 | tee -a $LOGFILE

# Report space freed
echo "[$timestamp] Cleanup completed" >> $LOGFILE
df -h >> $LOGFILE

# Email report
mail -s "Disk Cleanup Report" [email protected] < $LOGFILE

Schedule weekly:

echo "0 2 * * 0 /usr/local/bin/disk_cleanup.sh" | sudo crontab -

Monitoring Dashboard Creation

Create Daily Disk Report

sudo nano /usr/local/bin/daily_disk_report.sh
#!/bin/bash

# Daily Disk Usage Report
REPORT_FILE="/var/log/daily_disk_report_$(date +%Y%m%d).txt"

{
    echo "DISK USAGE REPORT"
    echo "Generated: $(date)"
    echo "Server: $(hostname)"
    echo "========================================"
    echo ""

    echo "FILESYSTEM USAGE:"
    echo "----------------"
    df -h | grep -vE 'tmpfs|cdrom'
    echo ""

    echo "INODE USAGE:"
    echo "------------"
    df -hi | grep -vE 'tmpfs|cdrom'
    echo ""

    echo "TOP 10 LARGEST DIRECTORIES:"
    echo "---------------------------"
    du -h --max-depth=2 / 2>/dev/null | sort -rh | head -10
    echo ""

    echo "TOP 10 LARGEST FILES:"
    echo "---------------------"
    find / -type f -exec du -h {} + 2>/dev/null | sort -rh | head -10
    echo ""

    echo "DIRECTORIES WITH MOST FILES:"
    echo "----------------------------"
    for dir in /var /home /opt; do
        echo -n "$dir: "
        find "$dir" -type f 2>/dev/null | wc -l
    done
    echo ""

} > $REPORT_FILE

# Email report
mail -s "Daily Disk Usage Report - $(hostname)" [email protected] < $REPORT_FILE

# Keep only last 30 days of reports
find /var/log -name "daily_disk_report_*.txt" -mtime +30 -delete

Troubleshooting Disk Space Issues

Identify What's Using Space When df and du Disagree

# Check for deleted files still held open
sudo lsof | grep deleted

# Find process holding deleted file
sudo lsof +L1

# Restart service to release file handles
sudo systemctl restart service_name

Find Hidden Space Usage

# Check all mount points
df -h

# Check for files in mount point directories
for mount in $(df | grep -vE 'tmpfs|cdrom' | awk '{print $6}'); do
    echo "Checking: $mount"
    sudo umount "$mount" 2>/dev/null && \
    du -sh "$mount" && \
    sudo mount "$mount"
done

Investigate Sudden Space Loss

# Find recently created large files
sudo find / -type f -size +100M -mtime -1 -exec ls -lh {} \; 2>/dev/null

# Find files modified in last hour
sudo find / -type f -mmin -60 -size +10M 2>/dev/null

# Check system logs for clues
sudo journalctl --since "1 hour ago" | grep -i error

Best Practices

1. Set Up Proactive Monitoring

Don't wait for disk full alerts:

# Monitor at 80% threshold, not 95%
THRESHOLD=80

2. Monitor Growth Trends

Track usage over time:

# Daily snapshots for trend analysis
echo "0 0 * * * df -h >> /var/log/disk_usage_$(date +\%Y\%m).log" | crontab -

3. Implement Log Rotation

Configure logrotate properly:

sudo nano /etc/logrotate.d/custom_app
/var/log/custom_app/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
}

4. Regular Cleanup Schedules

Automate cleanup tasks:

# Weekly cleanup every Sunday at 2 AM
0 2 * * 0 /usr/local/bin/disk_cleanup.sh

5. Use Separate Partitions

Isolate high-growth areas:

  • Separate /var/log partition
  • Separate /home partition
  • Separate /tmp partition
  • Separate application data partitions

6. Set Up Alerts at Multiple Thresholds

# Warning at 75%, critical at 90%
WARNING_THRESHOLD=75
CRITICAL_THRESHOLD=90

7. Document Normal Usage Patterns

Know your baseline:

# Monthly usage report
df -h > /root/disk_usage_baseline_$(date +%Y%m).txt

8. Monitor Inode Usage

Don't forget inodes:

# Include inode checks in monitoring
df -hi

9. Keep Historical Data

Maintain usage history:

# Archive monthly reports
mkdir -p /var/log/disk_history
mv /var/log/disk_usage_*.log /var/log/disk_history/

10. Test Cleanup Procedures

Verify cleanup scripts work:

# Test in non-production first
# Verify expected files are deleted
# Confirm space is actually freed

Conclusion

Effective disk space and inode monitoring is critical for maintaining healthy Linux systems. By implementing proactive monitoring, automated alerting, regular cleanup procedures, and trend analysis, you prevent disk-full emergencies and maintain optimal system performance.

Key takeaways:

  1. Monitor both space and inodes - either can be exhausted
  2. Set alert thresholds at 75-80%, not 95%
  3. Automate monitoring with scripts and cron jobs
  4. Track growth trends over time for capacity planning
  5. Implement log rotation to prevent log file growth
  6. Schedule regular cleanup of temporary files and caches
  7. Use appropriate tools - df, du, ncdu for different needs
  8. Document baselines for normal usage patterns
  9. Test cleanup procedures before emergencies
  10. Maintain historical data for trend analysis

Remember that disk monitoring isn't just about preventing full disks—it's about understanding system behavior, optimizing storage usage, and planning for future capacity needs. By following the practices and scripts in this guide, you can implement comprehensive disk monitoring that keeps your Linux infrastructure running smoothly.

Proactive monitoring prevents reactive firefighting. Invest time in proper monitoring infrastructure now to avoid critical outages later.