Backup folders, upload caches and exported reports grow until the disk is full. A small cleanup job that removes files after a set number of days keeps them in check. This guide shows how to build a safe find command, test it, and run it on a schedule.
Before you start
- A Linux VPS with Ubuntu 22.04 or 24.04, Debian 12, or AlmaLinux or Rocky Linux 8 or 9.
- An SSH session with sudo, or ownership of the folder you want to clean.
- The exact folder path, for example
/var/backups/myapp, and how many days of files to keep.
Warning: Deleted files do not go to a recycle bin. A wrong path or a missing condition can wipe a whole folder. Always do a dry run first, use full paths, and keep a recent backup of anything important.
Build the command
find selects files by age with -mtime. +7 means "last modified more than 7 days ago":
find /var/backups/myapp -type f -mtime +7-type fmatches files only, so folders are left alone.-mtime +7counts in whole days and drops fractions, so in practice it matches files at least 8 days old. Use-mmin +10080if you need exactly 7 days.
Dry run first
The command above only lists files. Read the list carefully, and count it:
find /var/backups/myapp -type f -mtime +7 | wc -lOnly when the list looks right, add -delete at the end:
find /var/backups/myapp -type f -mtime +7 -deleteAlways put -delete last. Placed earlier, it runs before your other conditions and removes everything under the folder.
Filter by name or extension
Limit the cleanup to certain files, for example compressed backups:
find /var/backups/myapp -type f -name "*.tar.gz" -mtime +14 -deleteSeveral extensions at once:
find /var/log/myapp -type f \( -name "*.gz" -o -name "*.log.[0-9]*" \) -mtime +30 -deleteStay inside one folder level, without touching subfolders:
find /var/backups/myapp -maxdepth 1 -type f -mtime +7 -deleteRemove empty folders too
After deleting files, empty subfolders may remain. Remove them with:
find /var/backups/myapp -mindepth 1 -type d -empty -delete-mindepth 1 protects the top folder itself.
Log what was deleted
For a record, print each file as it goes:
find /var/backups/myapp -type f -mtime +7 -print -delete >> /var/log/cleanup-myapp.logAutomate with cron
Put the command in a small script so the schedule stays readable:
sudo nano /usr/local/sbin/cleanup-myapp#!/bin/sh
set -eu
DIR=/var/backups/myapp
[ -d "$DIR" ] || exit 0
find "$DIR" -type f -name "*.tar.gz" -mtime +14 -print -deleteThe [ -d "$DIR" ] check stops the script if the folder is missing, rather than letting a typo search somewhere else. Make it executable and add a daily job to root's crontab:
sudo chmod 755 /usr/local/sbin/cleanup-myapp
sudo crontab -e30 3 * * * /usr/local/sbin/cleanup-myapp >> /var/log/cleanup-myapp.log 2>&1This runs every day at 03:30 server time. See Schedule cron jobs on Linux for the full syntax.
Or automate with a systemd timer
A timer logs to the journal and catches up after downtime. Create the service:
sudo nano /etc/systemd/system/cleanup-myapp.service[Unit]
Description=Delete old myapp backups
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/cleanup-myappAnd the timer:
sudo nano /etc/systemd/system/cleanup-myapp.timer[Unit]
Description=Daily cleanup of old myapp backups
[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true
[Install]
WantedBy=timers.targetEnable it:
sudo systemctl daemon-reload
sudo systemctl enable --now cleanup-myapp.timerMore detail is in systemd timers guide.
Alternative: tmpfiles.d
For temp and cache folders, systemd can age out files itself. Create a rule:
sudo nano /etc/tmpfiles.d/myapp.confd /var/cache/myapp 0750 myapp myapp 7dThis creates the folder if needed and lets systemd-tmpfiles-clean.timer remove entries not used for 7 days. The age check looks at access and change times too, not only mtime, so it suits caches better than backups. Test it at once with:
sudo systemd-tmpfiles --clean /etc/tmpfiles.d/myapp.confCheck it works
Run the job by hand and confirm the result:
sudo /usr/local/sbin/cleanup-myapp
find /var/backups/myapp -type f -mtime +14 | wc -lThe count should be 0. For a timer, systemctl list-timers cleanup-myapp.timer shows the next run, and journalctl -u cleanup-myapp.service shows the last one.
Troubleshooting
- Nothing is deleted: the files are newer than you think, or their mtime was preserved on copy. Check ages with
ls -l --time-style=long-iso. - Works by hand but not in cron: cron has a minimal environment. Use full paths everywhere and check the log file for errors.
- "Permission denied" in the log: the job runs as a user without rights to the folder. Run it from root's crontab or as the folder's owner.
- Too much was deleted: restore from backup and add stricter conditions, such as
-nameand-maxdepth. Keep the dry run step for every change.
Next steps
- Hunt for what else uses space: Find the largest files and folders.
