Delete Files and Folders Older Than X Days in Linux

Illustrated infographic summarizing: Delete Files and Folders Older Than X days

By Greg Nowak. Last updated 2026-09-08.

Old exports, generated reports, and temporary files can quietly fill a server. Linux’s find command can remove them by age, but the useful starting point is deciding which files your business can afford to lose.

This guide keeps the original 180-day example while separating file deletion from folder cleanup. The commands use GNU find, common on Linux. Replace /srv/myapp/exports with the actual directory you have agreed to clean, and preview every selection before deleting anything.

Why the original command needs changing

The original approach combined -mtime +180 with -exec rm -rf {} \;. That can select an old directory and recursively delete everything inside it, including recently modified files. A directory’s modification time does not tell you the age of every file beneath it.

Starting with /tmp/* also lets the shell expand the starting paths and normally leaves out hidden entries directly inside /tmp. Pass a quoted directory path to find instead, and let it search the contents.

For routine retention, select regular files by their own timestamps, then handle empty directories separately. Keep recursive removal of whole folders for cases where you have independently established that all their contents are disposable.

Choose the retention rule before the command

For a business owner or operations lead, the key question is whether a file is replaceable. An old generated export and an old customer upload may need completely different treatment. Agree the scope with whoever owns the application or client account.

What needs cleaning? Recommended approach Check first
Regenerable exports or reports Delete regular files by modification age. Can the team recreate them when requested?
Empty folders left behind Use a separate empty-directory pass. Does the application require those folders to exist?
Customer uploads or project archives Use an agreed retention and recovery process. Who authorizes removal, and what must remain available?
Shared system temporary files Review the operating system’s cleanup configuration. Is an existing policy already managing them?

Preview files older than 180 days

Start with a command that only lists matching files:

find '/srv/myapp/exports' -xdev -depth -mindepth 1 -type f -mtime +180 -print

-type f selects regular files. -mindepth 1 excludes the starting directory itself, while -xdev avoids descending onto other filesystems. -depth visits contents before their parent directories, matching the traversal used by the later deletion step. These controls are described in the GNU directory traversal documentation.

Using the directory directly includes hidden files within the search. By default, GNU find does not follow symbolic links it encounters; avoid adding -L casually, because it changes that scope. See GNU’s symbolic-link handling.

Review the listed paths with the application owner. If the directory mixes disposable exports with permanent documents, narrow the directory or add an agreed filename filter before proceeding.

What does “older than X days” actually mean?

-mtime measures time since the file’s contents were last modified, not when it was created, uploaded, or last needed. Copied or restored files can retain old modification timestamps, so this may not match your business retention date.

GNU find rounds elapsed time down to whole 24-hour periods. Consequently, -mtime +180 matches files at least 181 full days old. Likewise, -mtime +30 starts matching at 31 days. This follows the documented age-range rules.

Keep that boundary explicit in the maintenance instructions. If retention must start from an invoice date, project closure, or upload event, use the application’s records to select files.

Delete matching files, then review empty folders

After checking the preview and confirming that anything irreplaceable can be recovered, run:

find '/srv/myapp/exports' -xdev -depth -mindepth 1 -type f -mtime +180 -delete -print

The final -print lists successfully deleted paths. Keep -delete after the selection tests: expression order matters. GNU also warns that -delete implies depth-first traversal, so it should not be combined with -prune to exclude directories. See the deletion documentation.

Next, preview empty directories that meet the same age test:

find '/srv/myapp/exports' -xdev -depth -mindepth 1 -type d -empty -mtime +180 -print

If those folders can go, run:

find '/srv/myapp/exports' -xdev -depth -mindepth 1 -type d -empty -mtime +180 -delete -print

Removing files updates their parent directory’s modification time, so newly emptied folders may remain. That is expected with this age rule. To remove empty folders regardless of age, omit -mtime +180 from both the folder preview and deletion commands. Parent folders can become eligible as their children disappear during deletion.

Make scheduled cleanup maintainable

A preview is a snapshot, not a reservation: files can change before deletion. For active export directories, coordinate cleanup with the producing job or separate completed exports from work in progress.

Before adding a cron job or systemd timer, record the directory, retention rule, responsible person, and recovery procedure. Run with only the permissions needed, retain error output, and make failures visible to someone who can act.

For shared /tmp cleanup on systems using systemd, review systemd-tmpfiles and its existing configuration first. It already supports age-based cleanup through tmpfiles.d; avoid layering an unexplained deletion job over that policy.

If your team has inherited cleanup scripts without clear ownership, I can help review the rules, coordinate changes with your developers or hosting provider, and document the handover. Contact Greg to discuss your maintenance setup.

Related on GrN.dk

Need help with this kind of work?

Discuss your maintenance setup with Greg Get in touch with Greg.

Sources

Latest articles

An Apache version below 2.4.68 may still be patched. Package provenance, vendor advisories, module checks and runtime evidence reveal the real position.

PHP 8.2 security support ends on December 31, 2026. Here is how to audit, test, and migrate a mixed CMS estate without rushing production changes.

How Danish businesses can automate Gmail and Microsoft 365 with rapid sorting, limited permissions and human approval.

When WordPress jobs run late, check WP-Cron and queue capacity first. Diagnose triggers, handlers, and Action Scheduler without guesswork.

WordPress 7.1 makes speculative loading configurable. Here’s how to spot overlapping rules and test speed gains without adding hidden costs.

Multiple records for the same customer in HubSpot? Learn how CVR number matching, AI suggestions and human approval can help you clean up duplicates while keeping track of fields, associations and customer history.

Before a Google AI shopping pilot, check which products qualify, where your catalog data disagrees, and whether checkout reflects your delivery and return terms.

Check whether prompt caching reduces cost per completed task, accounting for cache writes, retries, review effort and the charges on your provider's bill.

A practical Drupal translation workflow for Danish service pages: German review, commercial approval, publication and keeping translations current after edits.

Build a weekly marketing report from GA4 and Google Ads with verified calculations, clear data caveats and a short AI draft to support your Monday meeting.