Linux VPS

Delete files older than X days automatically

Clean up old backups, logs and temp files on a schedule. Find files older than a set number of days, test with a dry run, delete them and automate it with cron, a systemd timer or tmpfiles.d.

IntermediateLinux server4 min read

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":

Bash
find /var/backups/myapp -type f -mtime +7
  • -type f matches files only, so folders are left alone.
  • -mtime +7 counts in whole days and drops fractions, so in practice it matches files at least 8 days old. Use -mmin +10080 if you need exactly 7 days.

Dry run first

The command above only lists files. Read the list carefully, and count it:

Bash
find /var/backups/myapp -type f -mtime +7 | wc -l

Only when the list looks right, add -delete at the end:

Bash
find /var/backups/myapp -type f -mtime +7 -delete

Always 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:

Bash
find /var/backups/myapp -type f -name "*.tar.gz" -mtime +14 -delete

Several extensions at once:

Bash
find /var/log/myapp -type f \( -name "*.gz" -o -name "*.log.[0-9]*" \) -mtime +30 -delete

Stay inside one folder level, without touching subfolders:

Bash
find /var/backups/myapp -maxdepth 1 -type f -mtime +7 -delete

Remove empty folders too

After deleting files, empty subfolders may remain. Remove them with:

Bash
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:

Bash
find /var/backups/myapp -type f -mtime +7 -print -delete >> /var/log/cleanup-myapp.log

Automate with cron

Put the command in a small script so the schedule stays readable:

Bash
sudo nano /usr/local/sbin/cleanup-myapp
Bash
#!/bin/sh
set -eu
DIR=/var/backups/myapp
[ -d "$DIR" ] || exit 0
find "$DIR" -type f -name "*.tar.gz" -mtime +14 -print -delete

The [ -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:

Bash
sudo chmod 755 /usr/local/sbin/cleanup-myapp
sudo crontab -e
30 3 * * * /usr/local/sbin/cleanup-myapp >> /var/log/cleanup-myapp.log 2>&1

This 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:

Bash
sudo nano /etc/systemd/system/cleanup-myapp.service
INI
[Unit]
Description=Delete old myapp backups

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/cleanup-myapp

And the timer:

Bash
sudo nano /etc/systemd/system/cleanup-myapp.timer
INI
[Unit]
Description=Daily cleanup of old myapp backups

[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true

[Install]
WantedBy=timers.target

Enable it:

Bash
sudo systemctl daemon-reload
sudo systemctl enable --now cleanup-myapp.timer

More detail is in systemd timers guide.

Alternative: tmpfiles.d

For temp and cache folders, systemd can age out files itself. Create a rule:

Bash
sudo nano /etc/tmpfiles.d/myapp.conf
d /var/cache/myapp 0750 myapp myapp 7d

This 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:

Bash
sudo systemd-tmpfiles --clean /etc/tmpfiles.d/myapp.conf

Check it works

Run the job by hand and confirm the result:

Bash
sudo /usr/local/sbin/cleanup-myapp
find /var/backups/myapp -type f -mtime +14 | wc -l

The 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 -name and -maxdepth. Keep the dry run step for every change.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.