Linux cron job guide
How to Check If Your Cron Job Ran
Five traditional methods to verify cron execution — and why they all leave gaps.
Method 1: Check the system log
Cron logs each invocation to syslog. The log file location varies by distribution.
grep CRON /var/log/syslog
# Output:
# Mar 31 03:00:01 server CRON[12345]: (root) CMD (/opt/scripts/backup.sh)grep CRON /var/log/cron
# Output:
# Mar 31 03:00:01 server CROND[12345]: (root) CMD (/opt/scripts/backup.sh)This confirms cron ran the command. It does not tell you whether the job succeeded, failed, or produced any output.
Method 2: Check cron mail
By default, cron emails stdout and stderr to the crontab owner after each run. You can override this with MAILTO.
# Check local mail for cron output
cat /var/mail/$USER
# Or set MAILTO in your crontab to receive output via email:
MAILTO="you@example.com"
0 3 * * * /opt/scripts/backup.shIn practice, most servers don't have a local mail transfer agent configured. Even with MAILTO, you get raw, unstructured output with no alerting on failure.
Method 3: Redirect output to a log file
Append stdout and stderr to a file so you can review it later.
# Redirect stdout and stderr to a log file
0 3 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1
# With timestamp
0 3 * * * echo "$(date): starting backup" >> /var/log/backup.log && \
/opt/scripts/backup.sh >> /var/log/backup.log 2>&1Better than nothing, but you need to remember to check the file. No log rotation means the disk can fill up. No alerting means failures are silent.
Method 4: Check the exit code in a wrapper
Write a wrapper script that captures $? and logs success or failure with a timestamp.
#!/bin/bash
# /opt/scripts/run-backup.sh
LOG="/var/log/backup.log"
echo "$(date): backup starting" >> "$LOG"
/opt/scripts/backup.sh >> "$LOG" 2>&1
EXIT=$?
if [ $EXIT -eq 0 ]; then
echo "$(date): backup completed successfully" >> "$LOG"
else
echo "$(date): backup FAILED (exit code $EXIT)" >> "$LOG"
fiThis is the best of the traditional approaches — you get structured logging with timestamps and exit codes. But you still have to SSH in and read the log. Nobody gets notified.
Method 5: Use systemctl for systemd timers
If you're using systemd timers instead of cron, you get better logging out of the box via journalctl.
# List all active timers and when they last ran
systemctl list-timers --all
# View logs for a specific timer's service
journalctl -u backup.service --since "1 hour ago"
# Check if the last run succeeded or failed
systemctl status backup.servicejournalctl captures full stdout/stderr automatically — better than syslog for debugging. But it still requires you to SSH in and look. See our full cron vs systemd timers comparison →
The problem with all of these
Syslog only shows invocation
It confirms cron ran the command. It doesn’t tell you if the job succeeded, failed, or how long it took.
Mail goes nowhere
Most servers don’t have a local MTA configured. Even when they do, nobody checks /var/mail.
Log files need maintenance
No log rotation? The disk fills up. The job stops running, and the log file is the reason.
Nobody gets notified
Every method above requires you to SSH in and look. Missed runs are invisible until something downstream breaks.
Every method above tells you what happened after you go looking. None of them tell you when a job simply doesn't run.
A better approach: automated monitoring
Instead of checking logs, have your job tell a monitoring service that it ran. If the check-in doesn't arrive on time, you get an alert.
# Your job pings CronDoctor on success or failure
0 3 * * * /opt/scripts/backup.sh \
&& curl -sf https://crondoctor.com/api/v1/ping/YOUR_ID \
|| curl -sf https://crondoctor.com/api/v1/ping/YOUR_ID/faildb-cleanup hasn't pinged in 26 hours. Last successful run was Tuesday at 03:00 UTC.
crontab -l to verify the schedule is still present.crontab -l | grep db-cleanupYou didn't check a log. CronDoctor noticed the job stopped and told you.
Stop checking logs. Get notified.
CronDoctor monitors your cron jobs and tells you when they miss, fail, or slow down — with an AI-powered diagnosis.