Implementing Fifo (First In First Out) On Media Folder To Maintain Diskspace - Bytesized Hosting Wiki

Name: implementing-fifo-first-in-first-out-on-media-folder-to-maintain-diskspace

Last reviewed by: Clipper, April 2026


Implementing FIFO on media folder to maintain disk space

FIFO means "First In, First Out", which means that the oldest element entered is the first one to get rid of

⚠️ DISCLAIMER: USE AT YOUR OWN RISK! This script permanently deletes your oldest files when disk space runs low. Think carefully before running this on a media folder you care about.


So I have some very media-hungry family members constantly adding stuff to my media folder, so instead of constantly deleting old stuff manually I wanted a script that checks if disk space is running low and, if so, deletes the oldest files in the folder until disk space has recovered to a specific percentage.

Found a nice script that does just that, and with a few tweaks by yours truly and the infamous Animazing (thanks!) it's working really well!


Instructions

Copy and paste the code below into a new file called something like deleteOldFiles.sh. Then run it with the following syntax:

./deleteOldFiles.sh [PATH] [limit in percentage]

For example, if you want it to run on your ~/media folder and delete files until disk space is no more than 90% full:

./deleteOldFiles.sh ~/media 90

The script checks if your disk space usage is higher than the threshold you specified, and if so, recursively finds the oldest file in the directory and deletes it. It repeats this process until usage is within the threshold.

⚠️ WARNING: When implementing this, strongly advise you modify the MAX_CYCLES variable to a small number — this is a built-in failsafe to prevent runaway scripts that could delete all your files.

⚠️ WARNING 2: Test this on a directory you don't care about first — for example an empty SABnzbd incomplete folder — before running it on your media folder.

If all works fine, you can add this to a cron job and have it run daily.


Script

#!/bin/bash
#
###############################################################################
# Author          : Louwrentius
# Initial release : August 2011
# Licence         : Simplified BSD License
###############################################################################

VERSION=1.01

# Mounted volume to be monitored.
MOUNT="$1"

# Maximum threshold of volume used as an integer (percentage).
# e.g. 95 = 95%
MAX_USAGE="$2"

# Failsafe mechanism: delete a maximum of MAX_CYCLES files, then raise an error.
# Prevents runaway scripts. Disable by choosing a high value.
MAX_CYCLES=1000
CYCLES=0

show_header () {
    echo
    echo DELETE OLD FILES $VERSION
    echo
}

show_header

reset () {
    OLDEST_FILE=""
    OLDEST_DATE=0
    ARCH=`uname`
}

reset

if [ -z "$MOUNT" ] || [ ! -e "$MOUNT" ] || [ ! -d "$MOUNT" ] || [ -z "$MAX_USAGE" ]
then
    echo "Usage: $0 <mountpoint> <threshold>"
    echo "Where threshold is a percentage."
    echo
    echo "Example: $0 /storage 90"
    echo "If disk usage of /storage exceeds 90% the oldest"
    echo "file(s) will be deleted until usage is below 90%."
    echo
    echo "Wrong command line arguments or another error:"
    echo
    echo "- Directory not provided as argument or"
    echo "- Directory does not exist or"
    echo "- Argument is not a directory or"
    echo "- no/wrong percentage supplied as argument."
    echo
    exit 1
fi

check_capacity () {
    TOTAL=`quota | tail -n1 | awk ' { print $2 }' | sed -e 's/G//'`
    CURRENT=`quota | tail -n1 | awk ' { print $1 }' | sed -e 's/G//'`
    let USAGE=(100*CURRENT)/TOTAL
    echo "Usage is $USAGE%"

    if [ ! "$?" == "0" ]
    then
        echo "Error: mountpoint $MOUNT not found in df output."
        exit 1
    fi

    if [ -z "$USAGE" ]
    then
        echo "Didn't get usage information of $MOUNT"
        echo "Mountpoint does not exist or please remove trailing slash."
        exit 1
    fi

    if [ "$USAGE" -gt "$MAX_USAGE" ]
    then
        echo "Usage of $USAGE% exceeded limit of $MAX_USAGE percent."
        return 0
    else
        echo "Usage of $USAGE% is within limit of $MAX_USAGE percent."
        return 1
    fi
}

check_age () {
    FILE="$1"
    if [ "$ARCH" == "Linux" ]
    then
        FILE_DATE=`stat -c %Z "$FILE"`
    elif [ "$ARCH" == "Darwin" ]
    then
        FILE_DATE=`stat -f %Sm -t %s "$FILE"`
    else
        echo "Error: unsupported architecture."
        echo "Send a patch for the correct stat arguments for your architecture."
    fi

    NOW=`date +%s`
    AGE=$((NOW-FILE_DATE))
    if [ "$AGE" -gt "$OLDEST_DATE" ]
    then
        export OLDEST_DATE="$AGE"
        export OLDEST_FILE="$FILE"
    fi
}

process_file () {
    FILE="$1"

    # Replace the following with whatever you want to do with the file.
    # You can delete, move, or perform any other action.
    echo "Deleting oldest file $FILE"
    rm -f "$FILE"
}

while check_capacity
do
    echo $CYCLES
    if [ "$CYCLES" -gt "$MAX_CYCLES" ]
    then
        echo "Error: after $MAX_CYCLES deleted files still not enough free space."
        exit 1
    fi

    reset

    FILES=`find "$MOUNT" -type f`

    IFS=$'\n'
    for x in $FILES
    do
        check_age "$x"
    done

    if [ -e "$OLDEST_FILE" ]
    then
        process_file "$OLDEST_FILE"
    else
        echo "Error: somehow, item $OLDEST_FILE disappeared."
    fi

    echo "Increasing Counter"
    CYCLES=$[CYCLES + 1]
done

Enjoy :)


Last Author Contributors Versions Last update
Clipper None 4 Sat, 11 Apr 2026 16:15:05 +0200