Disk Quotas on Linux: Complete Implementation Guide

Disk quotas are essential for managing storage resources in multi-user environments, preventing any single user or group from consuming excessive disk space. Whether you're managing a shared hosting server, university computer lab, or corporate file server, implementing disk quotas ensures fair resource allocation and prevents storage exhaustion.

This comprehensive guide covers complete disk quota implementation on Linux, from basic user quotas to advanced group quotas, grace periods, and automated monitoring.

Introduction to Disk Quotas

Disk quotas allow system administrators to limit the amount of disk space and number of files (inodes) that users and groups can consume on a filesystem. Quotas can be configured with both hard limits (absolute maximum) and soft limits (warnings with grace periods).

Why Implement Disk Quotas?

  • Prevent storage exhaustion: Stop individual users from filling up shared storage
  • Fair resource allocation: Ensure equitable disk space distribution
  • Capacity planning: Better predict and manage storage growth
  • Cost control: Manage storage costs in cloud and shared hosting environments
  • Security: Limit damage from compromised accounts or runaway processes
  • Compliance: Meet organizational policies for resource usage

Common Quota Use Cases

  • Shared hosting servers: Limit customer disk usage per account
  • University systems: Restrict student home directory sizes
  • Corporate file servers: Allocate departmental storage budgets
  • Email servers: Limit mailbox sizes
  • Web hosting: Control website storage consumption
  • Development environments: Manage project storage allocations
  • Home directories: Prevent users from filling home partitions

Quota Terminology

  • Soft limit: Warning threshold; can be exceeded temporarily
  • Hard limit: Absolute maximum that cannot be exceeded
  • Grace period: Time users can exceed soft limits before enforcement
  • Block quota: Limits on disk space (measured in blocks/kilobytes)
  • Inode quota: Limits on number of files and directories
  • User quota: Per-user limits
  • Group quota: Per-group limits

Prerequisites

Before implementing disk quotas, ensure you have:

  • Root or sudo access on the Linux system
  • Filesystem that supports quotas (ext4, XFS, Btrfs)
  • Quota tools installed
  • Users and groups configured on the system
  • Understanding of filesystem block sizes
  • Backup of critical data before enabling quotas

Supported Filesystems

Most modern Linux filesystems support quotas:

  • ext3/ext4: Full support for user and group quotas
  • XFS: Full support with project quotas additionally
  • Btrfs: Limited quota support (subvolume quotas)
  • ReiserFS: Supports quotas (less common)

Step 1: Install Quota Tools

On Debian/Ubuntu

sudo apt update
sudo apt install quota quotatool

On CentOS/RHEL/Rocky Linux

sudo yum install quota
# or
sudo dnf install quota

Verify Installation

quota --version

Expected output:

Quota utilities version 4.05

Step 2: Enable Quotas in fstab

Quotas must be enabled at the filesystem mount level.

Backup fstab

sudo cp /etc/fstab /etc/fstab.backup.$(date +%Y%m%d)

Edit fstab

sudo nano /etc/fstab

Add Quota Options

For user quotas only:

UUID=your-uuid  /home  ext4  defaults,usrquota  0  2

For user and group quotas:

UUID=your-uuid  /home  ext4  defaults,usrquota,grpquota  0  2

For XFS filesystem:

UUID=your-uuid  /home  xfs  defaults,usrquota,grpquota  0  2

Example fstab with Quotas

# /etc/fstab

# Root partition
UUID=root-uuid  /  ext4  defaults,errors=remount-ro  0  1

# Home partition with quotas
UUID=home-uuid  /home  ext4  defaults,usrquota,grpquota  0  2

# Data partition with quotas
UUID=data-uuid  /mnt/data  ext4  defaults,usrquota,grpquota  0  2

Apply fstab Changes

For ext3/ext4 filesystems, remount:

sudo mount -o remount /home

Or for all filesystems:

sudo mount -a

Verify quota options:

mount | grep /home

Output should show:

/dev/sdb1 on /home type ext4 (rw,relatime,quota,usrquota,grpquota)

Step 3: Create Quota Database Files

For ext3/ext4 Filesystems

Create quota database files:

# Create quota files for /home
sudo quotacheck -cugm /home

Options explained:

  • -c: Create quota files
  • -u: Check user quotas
  • -g: Check group quotas
  • -m: Don't try to remount read-only

This creates two files:

  • /home/aquota.user (user quotas)
  • /home/aquota.group (group quotas)

For XFS Filesystems

XFS handles quota files internally, no quotacheck needed:

# Just enable quotas
sudo xfs_quota -x -c 'state' /home

Verify Quota Files

ls -la /home/aquota.*

Output:

-rw-------  1 root root 8192 Jan 11 10:30 /home/aquota.group
-rw-------  1 root root 8192 Jan 11 10:30 /home/aquota.user

Step 4: Enable Quota System

For ext3/ext4

Turn on quota system:

sudo quotaon -v /home

Output:

/dev/sdb1 [/home]: group quotas turned on
/dev/sdb1 [/home]: user quotas turned on

For XFS

Quotas are enabled automatically when mounted with quota options.

Verify:

sudo xfs_quota -x -c 'state' /home

Check Quota Status

sudo quotaon -p /home

Or:

sudo repquota -s /home

Step 5: Set User Quotas

There are two methods to set quotas: interactive editor or command-line.

Method 1: Interactive Editor (edquota)

# Edit quota for user 'john'
sudo edquota -u john

This opens an editor with:

Disk quotas for user john (uid 1001):
  Filesystem                   blocks       soft       hard     inodes     soft     hard
  /dev/sdb1                         0     500000    1000000          0        0        0

Fields explained:

  • blocks: Current usage (1 block = 1KB typically)
  • soft: Soft limit for blocks (500MB in example)
  • hard: Hard limit for blocks (1GB in example)
  • inodes: Current number of files/directories
  • soft: Soft limit for inodes (0 = unlimited)
  • hard: Hard limit for inodes (0 = unlimited)

Set limits:

Disk quotas for user john (uid 1001):
  Filesystem                   blocks       soft       hard     inodes     soft     hard
  /dev/sdb1                         0     512000    1048576          0     5000    10000

This sets:

  • Soft limit: 500MB (512000 KB)
  • Hard limit: 1GB (1048576 KB)
  • Inode soft: 5000 files
  • Inode hard: 10000 files

Save and exit.

Method 2: Command Line (setquota)

# Set quota for user john
# Format: setquota -u username block_soft block_hard inode_soft inode_hard filesystem
sudo setquota -u john 512000 1048576 5000 10000 /home

For 1GB soft, 2GB hard, 10000 files soft, 20000 hard:

sudo setquota -u john 1048576 2097152 10000 20000 /home

Set Quotas in Human-Readable Format

Using quotatool (if installed):

# Set 500MB soft, 1GB hard
sudo quotatool -u john -bq 500M -l '1G' /home

Verify User Quota

sudo quota -vs john

Or:

sudo repquota -s -u /home

Step 6: Set Group Quotas

Similar to user quotas but for groups.

Interactive Editor

sudo edquota -g developers

Command Line

# Set quota for group 'developers'
# 5GB soft, 10GB hard, 50000 files soft, 100000 hard
sudo setquota -g developers 5242880 10485760 50000 100000 /home

Verify Group Quota

sudo quota -g developers

Step 7: Set Grace Periods

Grace periods define how long users can exceed soft limits.

Set Grace Period

# Edit grace period
sudo edquota -t

Default editor shows:

Grace period before enforcing soft limits for users:
Time units may be: days, hours, minutes, or seconds
  Filesystem             Block grace period     Inode grace period
  /dev/sdb1                     7days                  7days

Common grace periods:

  • 7days (default)
  • 168hours
  • 10080minutes
  • 0 (no grace period)

Change to 14 days:

Grace period before enforcing soft limits for users:
Time units may be: days, hours, minutes, or seconds
  Filesystem             Block grace period     Inode grace period
  /dev/sdb1                    14days                 14days

Set Grace Period via Command

# Set 7-day grace period
sudo setquota -t 604800 604800 /home

Step 8: Copy Quotas Between Users

Apply same quota limits to multiple users.

Copy Quota from Template User

# Set quota for template user
sudo setquota -u template_user 1048576 2097152 10000 20000 /home

# Copy to other users
sudo edquota -p template_user -u user1 user2 user3

Copy to All Users in Group

# Get users in group
USERS=$(getent group developers | cut -d: -f4 | tr ',' ' ')

# Copy quota to each user
for user in $USERS; do
    sudo edquota -p template_user -u $user
done

Step 9: Monitor Quota Usage

Check User Quota Usage

User checking their own quota:

quota -vs

Administrator checking user quota:

sudo quota -vs john

Generate Quota Reports

Summary of all users:

sudo repquota -s /home

Output:

*** Report for user quotas on device /dev/sdb1
Block grace time: 7days; Inode grace time: 7days
                        Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
root      --      20K      0K      0K              2     0     0
john      --    450M    500M      1G            4500  5000 10000
mary      +-    520M    500M      1G  6days    5200  5000 10000
bob       --    200M    500M      1G            2000  5000 10000

Legend:

  • --: Within limits
  • +-: Exceeded soft limit (in grace period)
  • ++: Exceeded soft limit (grace period expired)

Detailed report:

sudo repquota -aug /home

Check Quota for Specific User

sudo quota -u john -s

List Users Exceeding Quota

sudo repquota /home | awk '$3 > 0 && $5 != "0" { print $1, $3, $5 }'

Automated Quota Management

Create Quota Monitoring Script

sudo nano /usr/local/bin/quota_monitor.sh

Add content:

#!/bin/bash

# Quota monitoring script
THRESHOLD=90
FILESYSTEM="/home"
LOGFILE="/var/log/quota_monitor.log"

# Function to send alert
send_alert() {
    local user=$1
    local usage=$2
    echo "$(date): WARNING - User $user at ${usage}% quota usage" >> $LOGFILE
    # Uncomment to send email
    # echo "User $user has reached ${usage}% of quota" | mail -s "Quota Alert" [email protected]
}

# Check all users
repquota -u $FILESYSTEM | awk 'NR>5 {
    if ($4 > 0 && $3 > 0) {
        usage = ($3 / $4) * 100
        if (usage >= '$THRESHOLD') {
            print $1, usage
        }
    }
}' | while read user usage; do
    send_alert $user $usage
done

Make executable:

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

Automate with Cron

# Run daily at 9 AM
echo "0 9 * * * /usr/local/bin/quota_monitor.sh" | sudo crontab -

Create Quota Report Script

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

# Generate quota usage report
FILESYSTEM="/home"
REPORT_FILE="/var/log/quota_report_$(date +%Y%m%d).txt"

echo "Quota Usage Report - $(date)" > $REPORT_FILE
echo "======================================" >> $REPORT_FILE
echo "" >> $REPORT_FILE

repquota -s $FILESYSTEM >> $REPORT_FILE

# Find top 10 users by disk usage
echo "" >> $REPORT_FILE
echo "Top 10 Users by Disk Usage:" >> $REPORT_FILE
echo "======================================" >> $REPORT_FILE
repquota -u $FILESYSTEM | sort -k3 -n -r | head -n 15 >> $REPORT_FILE

echo "Report saved to: $REPORT_FILE"

Make executable and schedule:

sudo chmod +x /usr/local/bin/quota_report.sh
echo "0 0 * * 0 /usr/local/bin/quota_report.sh" | sudo crontab -  # Weekly on Sunday

Advanced Quota Features

Project Quotas (XFS Only)

XFS supports project quotas for directory trees.

Enable Project Quotas

Edit fstab:

UUID=xfs-uuid  /data  xfs  defaults,prjquota  0  2

Remount:

sudo mount -o remount /data

Create Project

Define project in /etc/projects:

echo "100:/data/project1" | sudo tee -a /etc/projects

Define project name in /etc/projid:

echo "project1:100" | sudo tee -a /etc/projid

Set Project Quota

# Initialize project
sudo xfs_quota -x -c 'project -s project1' /data

# Set quota (5GB)
sudo xfs_quota -x -c 'limit -p bhard=5g project1' /data

Check Project Quota

sudo xfs_quota -x -c 'report -pbh' /data

Quota Warnings and User Notifications

Create user notification script:

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

FILESYSTEM="/home"
THRESHOLD=80

repquota -u $FILESYSTEM | awk 'NR>5 {
    if ($4 > 0 && $3 > 0) {
        usage = ($3 / $4) * 100
        if (usage >= '$THRESHOLD') {
            print $1, $3, $4, int(usage)
        }
    }
}' | while read user used limit percentage; do
    # Send warning to user
    echo "Your disk usage is at ${percentage}%. Used: ${used}KB of ${limit}KB. Please clean up old files." | \
    write $user 2>/dev/null || \
    mail -s "Disk Quota Warning" $user <<EOF
Your disk quota is at ${percentage}% capacity.

Current usage: ${used} KB
Quota limit: ${limit} KB

Please remove unnecessary files to free up space.
EOF
done

Troubleshooting Common Issues

Issue: Quotacheck Fails

Cause: Filesystem mounted, or quota already enabled.

Solution:

# Disable quotas first
sudo quotaoff -av

# Unmount filesystem (if possible)
sudo umount /home

# Run quotacheck
sudo quotacheck -cugm /home

# Remount and enable quotas
sudo mount /home
sudo quotaon -av

Issue: Quotas Not Enforced

Cause: Quotas not enabled on filesystem.

Solution:

# Check if quotas are on
sudo quotaon -p /home

# If off, turn on
sudo quotaon -v /home

# Verify mount options
mount | grep /home

Issue: "Quota file not found"

Cause: Quota database files missing.

Solution:

# Recreate quota files
sudo quotaoff /home
sudo quotacheck -cugm /home
sudo quotaon -v /home

Issue: User Can't Write Despite Available Quota

Cause: Inode limit reached.

Solution:

# Check inode usage
sudo quota -vs username

# Increase inode limits if needed
sudo setquota -u username 1048576 2097152 20000 40000 /home

Issue: Grace Period Not Working

Cause: Grace period not set or already expired.

Solution:

# Set grace period
sudo edquota -t

# Check user grace period status
sudo repquota -s /home | grep username

Issue: Quotas Reset After Reboot

Cause: Quotas not enabled in fstab or quota service not enabled.

Solution:

# Verify fstab has quota options
grep quota /etc/fstab

# Enable quota service
sudo systemctl enable quota
sudo systemctl start quota

Best Practices for Disk Quotas

1. Set Realistic Limits

Base limits on actual usage patterns:

# Analyze current usage
sudo du -sh /home/*

# Set limits with headroom
# If average usage is 300MB, set soft to 500MB, hard to 1GB

2. Use Soft and Hard Limits Together

Always set both with appropriate gap:

# Soft: 500MB, Hard: 1GB (100% increase for buffer)
sudo setquota -u username 512000 1048576 5000 10000 /home

3. Set Reasonable Grace Periods

Common practices:

  • Development: 3-7 days
  • Production: 1-3 days
  • Critical systems: 1 day or less
sudo edquota -t
# Set 7days for normal environments

4. Don't Forget Inode Limits

File count can be as limiting as space:

# Include inode limits
sudo setquota -u username 1048576 2097152 10000 20000 /home

5. Regular Monitoring

# Daily quota checks
echo "0 8 * * * /usr/local/bin/quota_monitor.sh" | sudo crontab -

6. Document Quota Policies

Create policy document:

sudo nano /etc/quota_policy.txt
Disk Quota Policy
=================

Standard User: 500MB soft, 1GB hard
Power User: 2GB soft, 5GB hard
Department: 50GB soft, 100GB hard

Grace Period: 7 days
Review Period: Monthly

Contact: [email protected]

7. Test in Non-Production First

Always test quota configuration:

# Create test user
sudo useradd testquota

# Set small quota for testing
sudo setquota -u testquota 1024 2048 100 200 /home

# Test exceeding limits
sudo su - testquota
dd if=/dev/zero of=testfile bs=1M count=3

8. Backup Quota Configuration

# Backup quota database
sudo cp /home/aquota.user /backup/aquota.user.$(date +%Y%m%d)
sudo cp /home/aquota.group /backup/aquota.group.$(date +%Y%m%d)

# Export quota configuration
sudo repquota -u /home > /backup/quota_config_$(date +%Y%m%d).txt

9. Provide User Self-Service

Create wrapper script for users:

sudo nano /usr/local/bin/myquota
#!/bin/bash
echo "Your Disk Quota Status:"
echo "======================="
quota -vs
echo ""
echo "For assistance, contact: [email protected]"

10. Regular Quota Database Maintenance

# Monthly quota check
echo "0 2 1 * * quotacheck -augm && quotaon -av" | sudo crontab -

Quota Implementation Checklist

Use this checklist when implementing quotas:

  • Install quota packages
  • Add quota options to /etc/fstab
  • Remount filesystems with quota options
  • Create quota database files (ext4) or enable (XFS)
  • Turn on quota system
  • Set user quotas for existing users
  • Set group quotas if needed
  • Configure grace periods
  • Test quota enforcement
  • Create monitoring scripts
  • Schedule automated quota reports
  • Document quota policies
  • Train users on quota system
  • Set up alert mechanisms
  • Plan for quota adjustments

Conclusion

Disk quotas are essential for managing storage resources in multi-user Linux environments. By implementing user and group quotas with appropriate soft/hard limits and grace periods, you ensure fair resource allocation and prevent storage exhaustion.

Key takeaways:

  1. Enable quotas in fstab with usrquota and grpquota options
  2. Create quota databases with quotacheck (ext4) or enable (XFS)
  3. Set realistic limits based on actual usage patterns
  4. Use soft and hard limits with appropriate gaps
  5. Configure grace periods (typically 7 days)
  6. Monitor quota usage with automated scripts
  7. Notify users approaching limits proactively
  8. Document policies clearly for users
  9. Regular maintenance of quota databases
  10. Test thoroughly before production deployment

Proper quota implementation protects shared storage resources while providing fair allocation to all users. By following the procedures and best practices in this guide, you can deploy effective disk quota systems that prevent storage issues and ensure equitable resource distribution across your Linux infrastructure.

Remember that quotas are a management tool, not a replacement for proper capacity planning. Regularly review quota usage trends and adjust limits as organizational needs evolve.