When your system shuts down during a scheduled cron job execution, the missed jobs won't automatically run when the system boots back up. Cron is designed to execute tasks at specific times, not to maintain a queue of missed executions. This is fundamental cron behavior across Unix-like systems.
# Example crontab entry that would be missed during shutdown 30 2 * * * /usr/bin/backup_db.sh
The cron daemon doesn't track execution history or maintain state between reboots. It simply checks the current time against the crontab schedule at regular intervals. If the system was off when a job should have run, that moment has passed and cron moves on to the next scheduled time.
For critical tasks that must run even after system downtime, consider these solutions:
1. Use anacron (for systems that support it)
# Example anacrontab entry that will run missed jobs 1 5 daily.backup /usr/bin/backup_db.sh
2. Implement a custom wrapper script with execution tracking
#!/bin/bash # cron_wrapper.sh LOG_FILE=/var/log/cron_jobs.log JOB_ID=$1 COMMAND=$2 if ! grep -q "$JOB_ID:completed" $LOG_FILE; then $COMMAND echo "$(date): $JOB_ID:completed" >> $LOG_FILE fi
3. Use systemd timers (on modern Linux systems)
# Example systemd timer unit [Unit] Description=Run backup daily with persistence [Timer] OnCalendar=*-*-* 02:30:00 Persistent=true [Install] WantedBy=timers.target
Implement monitoring to detect missed cron jobs:
# Simple monitoring script to check for missed executions #!/bin/bash LAST_RUN=$(stat -c %Y /var/log/backup.log) CURRENT_TIME=$(date +%s) HOURS_SINCE=$(( (CURRENT_TIME - LAST_RUN) / 3600 )) if [ $HOURS_SINCE -gt 24 ]; then mail -s "Backup job missed" admin@example.com <<< "Last backup was $HOURS_SINCE hours ago" fi
- For critical jobs, implement redundant scheduling (cron + anacron)
- Use centralized logging to track job executions
- Consider distributed job schedulers for high-availability systems
- Implement alerting for missed jobs
- Document your recovery procedures for missed jobs
When your system shuts down during a scheduled cron job execution, the missed jobs are not automatically executed when the system reboots. Cron operates on a strict schedule - if the system isn't running at the exact scheduled time, those jobs are simply skipped.
The cron daemon maintains no persistent state about missed executions. It only looks forward to the next scheduled time for each job. This design is intentional for several reasons:
- Prevents resource contention from multiple jobs running simultaneously
- Avoids unpredictable system behavior during recovery
- Maintains the principle of explicit scheduling
For critical tasks that must run even after system downtime, consider these approaches:
1. Using anacron (for Linux Systems)
anacron is specifically designed for systems that aren't running 24/7:
# Example anacrontab entry
1 5 backup-job /usr/local/bin/backup_script.sh
This would run the backup job if it was missed, with a 5-minute delay after system startup.
2. Implementing a Custom Wrapper Script
Create a script that tracks last execution time and handles missed runs:
#!/bin/bash
LOCKFILE=/var/lock/myjob.lock
TIMESTAMPFILE=/var/lock/myjob.timestamp
# Check if we need to run (more than 24 hours since last run)
if [ -f "$TIMESTAMPFILE" ]; then
last_run=$(cat $TIMESTAMPFILE)
current_time=$(date +%s)
if (( current_time - last_run < 86400 )); then
exit 0
fi
fi
# Acquire lock
exec 200>$LOCKFILE
flock -n 200 || exit 1
# Main job logic here
/usr/local/bin/your_actual_script.sh
# Update timestamp
date +%s > $TIMESTAMPFILE
# Release lock
flock -u 200
3. Systemd Timer Units (Modern Linux Systems)
Systemd timers can be configured to catch up missed executions:
# Example timer unit file
[Unit]
Description=Run missed jobs after boot
[Timer]
OnBootSec=5min
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
- For truly critical jobs, implement external monitoring that alerts you about missed executions
- Consider using distributed job schedulers like Celery or Kubernetes CronJobs for more robust scheduling
- Always include proper logging in your scripts to track execution history
- For database-related jobs, implement transaction-based tracking rather than relying on system timestamps
Implement a simple monitoring script to check for missed jobs:
#!/bin/bash
# Check last execution time of important jobs
critical_jobs=("backup" "report-generation" "data-sync")
for job in "${critical_jobs[@]}"; do
last_run=$(grep "$job" /var/log/cron.log | tail -1 | cut -d' ' -f1-3)
last_run_epoch=$(date -d "$last_run" +%s 2>/dev/null)
if [ -z "$last_run_epoch" ] || [ $(date +%s) -gt $((last_run_epoch + 86400)) ]; then
echo "ALERT: Job $job hasn't run in over 24 hours" | mail -s "Cron Job Alert" admin@example.com
fi
done