Temporary files are useful until they outlive the task that created them. Old exports, upload fragments, generated thumbnails, cache entries, and abandoned archives can consume storage, slow backups, and eventually cause application failures. A web cron job can remove them reliably, but cleanup code must be much more cautious than ordinary file creation.
Define exactly what is temporary
Start with an allowlist of dedicated directories that contain disposable data. Never point a cleanup job at a broad application root, home directory, or user-provided path. Keep uploads, configuration, logs, and backups outside the cleanup scope unless they have their own reviewed retention policy.
For every file class, document who creates it, the minimum safe age, whether it can still be in use, and how it can be recovered. A cache entry may be safe after hours, while a generated report may need weeks.
Use age and state, not filename guesses
Select candidates using trusted metadata such as creation time, last successful access recorded by the application, database state, or a completion marker. Filename patterns alone are fragile and can match active or unrelated files.
Write new artifacts to a staging suffix and rename them atomically only when complete. The cleanup job can ignore staging files that are still young and investigate old ones separately.
Protect paths before deleting
Resolve every candidate to an absolute canonical path and confirm that it remains inside an approved cleanup directory. Reject symbolic links and traversal sequences unless the design explicitly handles them. Never build destructive paths from unchecked query parameters.
Run the worker with the least filesystem permissions required. It should not be able to modify application code, credentials, or system directories even if a bug reaches the deletion step. Apply the endpoint safeguards from securing web cron endpoints to the trigger itself.
Begin with a dry run
A dry-run mode should enumerate candidates, sizes, reasons, and proposed actions without changing anything. Review several real runs and compare the list with application behavior. Add explicit exclusions for sentinel files, active workspaces, and recent sessions.
Keep the same selection code for dry and live modes so the preview is trustworthy. Only the final action should change.
Quarantine before permanent removal
When storage allows it, move candidates to a quarantine directory first. A later job can permanently delete quarantined items after a shorter recovery window. Moving within the same filesystem is usually atomic and gives operators time to reverse a bad rule.
Use unique names in quarantine and store a manifest containing the original path, size, checksum, reason, and timestamp. Do not expose quarantined files through the public web server.
Process files in bounded batches
Deleting millions of files in one HTTP request risks timeouts and heavy disk load. Limit each run by file count, total bytes, or elapsed time. Save a cursor or re-scan safely on the next run. Return a concise result while detailed diagnostics remain in private logs.
If the job can outlast the scheduler request, place work in a background queue. Our guide to scheduling HTTP requests and webhooks explains how web cron triggers can start server-side work cleanly.
Prevent overlapping cleanup jobs
Two cleanup workers can race over the same candidate or overwhelm storage. Acquire an atomic lock before scanning and set a realistic expiration for abandoned runs. Make each file operation idempotent so a retry treats an already moved or deleted file as a known outcome.
See preventing overlapping cron jobs for practical file and database lock patterns.
Log evidence without leaking data
Record the rule version, start and finish times, counts, bytes recovered, skipped items, failures, and quarantine totals. Avoid writing sensitive filenames or user content to broad-access logs. Use stable internal identifiers where possible.
Alert on unexpected jumps in candidate count, repeated permission errors, a cleanup job that stops reclaiming space, or free storage approaching a critical threshold. The signals in cron job monitoring help distinguish a healthy no-op from a broken worker.
Test failure and recovery paths
Test locked files, permission failures, symbolic links, path traversal attempts, concurrent writers, partial moves, low disk space, and a worker terminated mid-batch. Confirm that retries are safe and quarantined items can be restored.
Before enabling deletion, follow the web cron testing checklist and run the job against a disposable copy of production-like directories.
Safe cleanup checklist
- Allowlist narrow cleanup directories.
- Define retention by file class and application state.
- Resolve and validate every path.
- Preview candidates in dry-run mode.
- Quarantine before permanent deletion when possible.
- Process bounded batches under an atomic lock.
- Monitor reclaimed space, skips, and failures.
Good cleanup automation is conservative by design. Narrow scope, explicit retention, dry runs, quarantine, bounded work, and strong monitoring turn a risky delete operation into a predictable maintenance routine.
