crontoolModern Cron Expression Builder

Weekly Cleanup Cron Job — Delete Temp Files Every Sunday at 3am

Run a cleanup script every Sunday at 3am to delete temp files, rotate logs, and prune stale uploads automatically.

0 3 * * 0
At 03:00 AM, only on Sunday
Open in builder →

What this schedule does

The expression 0 3 * * 0 fires at exactly 3:00 AM every Sunday. The five fields mean: minute=0, hour=3, any day of month, any month, day=0 (Sunday). It runs once per week, guaranteed to skip all six other days.

Sunday at 3am is ideal for cleanup work: traffic is at its weekly minimum, the weekend gives time for any recovery if something unexpected gets deleted, and the fresh start on Monday benefits from a clean filesystem. Common uses include removing accumulated temp files, pruning uploaded files older than 30 days, rotating application logs, and clearing expired cache entries from disk.

What to clean up

A weekly cleanup job typically targets several categories of stale data:

Always log what was deleted — including file count and bytes freed — so you can audit the job and recover from mistakes. Use find -print to dry-run before adding -delete.

Platform snippets

Standard crontab
# crontab -e
0 3 * * 0    /usr/local/bin/weekly-cleanup.sh

# weekly-cleanup.sh
#!/bin/bash
set -euo pipefail
LOG=/var/log/cleanup.log
echo "=== Cleanup $(date) ===" >> "$LOG"

# Delete temp files older than 7 days
find /tmp -mindepth 1 -mtime +7 -delete 2>>"$LOG" && echo "Cleared /tmp" >> "$LOG"

# Delete app uploads older than 30 days
find /var/app/uploads -name '*.tmp' -mtime +30 -delete 2>>"$LOG"

# Rotate logs larger than 100MB
find /var/log/app -name '*.log' -size +100M -exec gzip {} \; 2>>"$LOG"

# Remove compressed logs older than 90 days
find /var/log/app -name '*.log.gz' -mtime +90 -delete 2>>"$LOG"

echo "Done. Disk usage: $(df -h / | tail -1)" >> "$LOG"
GitHub Actions
on:
  schedule:
    - cron: '0 3 * * 0'   # UTC — runs every Sunday at 3am UTC

jobs:
  cleanup:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Delete stale artifacts from S3
        run: |
          aws s3 ls s3://${{ secrets.BUCKET }}/uploads/ \
            | awk '{print $4}' \
            | while read key; do
                age=$(aws s3api head-object --bucket ${{ secrets.BUCKET }} \
                  --key "uploads/$key" --query LastModified --output text)
                # delete objects older than 30 days
                python3 -c "
          import sys, datetime
          age = datetime.datetime.fromisoformat('$age'.replace('Z','+00:00'))
          if (datetime.datetime.now(datetime.timezone.utc) - age).days > 30:
              sys.exit(0)
          sys.exit(1)" && aws s3 rm s3://${{ secrets.BUCKET }}/uploads/$key
              done
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_DEFAULT_REGION: us-east-1
AWS EventBridge
# EventBridge cron (6 fields — adds year, UTC)
cron(0 3 ? * SUN *)

# Trigger a Lambda that runs cleanup logic
# Lambda handler example (Python)
import boto3, datetime, os

s3 = boto3.client('s3')
BUCKET = os.environ['BUCKET']
CUTOFF_DAYS = int(os.environ.get('CUTOFF_DAYS', '30'))

def handler(event, context):
    cutoff = datetime.datetime.now(datetime.timezone.utc) \
             - datetime.timedelta(days=CUTOFF_DAYS)
    paginator = s3.get_paginator('list_objects_v2')
    deleted = 0
    for page in paginator.paginate(Bucket=BUCKET, Prefix='uploads/tmp/'):
        for obj in page.get('Contents', []):
            if obj['LastModified'] < cutoff:
                s3.delete_object(Bucket=BUCKET, Key=obj['Key'])
                deleted += 1
    return {'deleted': deleted}
Kubernetes CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
  name: weekly-cleanup
spec:
  schedule: "0 3 * * 0"
  timeZone: "UTC"
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: cleanup
            image: alpine:3.20
            command:
            - /bin/sh
            - -c
            - |
              echo "Starting cleanup $(date)"
              find /data/uploads -mtime +30 -type f -delete
              find /data/tmp -mtime +7 -type f -delete
              echo "Done. Files removed."
            volumeMounts:
            - name: data
              mountPath: /data
          volumes:
          - name: data
            persistentVolumeClaim:
              claimName: app-data-pvc
          restartPolicy: OnFailure

Timezone note

Standard crontab uses the system timezone. GitHub Actions and AWS EventBridge run in UTC — if you're on US Eastern time (UTC-5), use 0 8 * * 0 to fire at 3am ET. For US Pacific (UTC-8), use 0 11 * * 0. Kubernetes 1.27+ supports spec.timeZone: "America/Los_Angeles" so you can write the local time directly.

More guides

Database backup Morning brief Cache warm-up Weekly metrics report