Cron Syntax
┌───────── minute (0-59)
│ ┌───────── hour (0-23)
│ │ ┌───────── day of month (1-31)
│ │ │ ┌───────── month (1-12)
│ │ │ │ ┌───────── day of week (0-7, 0 and 7 = Sunday)
│ │ │ │ │
* * * * * command
Common Schedules
| Schedule | Expression | Description |
|---|---|---|
| Every minute | * * * * * |
Monitoring scripts |
| Every 5 minutes | */5 * * * * |
Health checks |
| Hourly | 0 * * * * |
Log rotation, cache clear |
| Daily at midnight | 0 0 * * * |
Backups, reports |
| Daily at 3 AM | 0 3 * * * |
Maintenance tasks |
| Weekly (Sunday midnight) | 0 0 * * 0 |
Weekly reports |
| Monthly (1st at midnight) | 0 0 1 * * |
Monthly cleanup |
Editing Crontab
# Edit current user's crontab
crontab -e
# Edit another user's crontab (as root)
sudo crontab -u deploy -e
# List current cron jobs
crontab -l
System-Wide Cron
# Drop-in files in /etc/cron.d/
echo "*/5 * * * * deploy /opt/scripts/healthcheck.sh" | sudo tee /etc/cron.d/healthcheck
Best Practices
Always redirect output
# Log output
*/5 * * * * /opt/scripts/backup.sh >> /var/log/backup-cron.log 2>&1
# Discard output (only for tested scripts)
0 3 * * * /opt/scripts/cleanup.sh > /dev/null 2>&1
Use flock to prevent overlap
# Prevents second instance from starting if first is still running
*/5 * * * * flock -n /tmp/backup.lock /opt/scripts/backup.sh
Set PATH and environment
# At the top of your crontab
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=admin@example.com
Use absolute paths
# Bad — cron doesn't load your shell profile
*/5 * * * * node app.js
# Good
*/5 * * * * /usr/bin/node /var/www/myapp/app.js
Tip Test your cron commands manually first. Many cron failures happen because the command works in your shell (which has PATH, env vars, etc.) but not in cron's minimal environment.
Debugging Cron
# Check cron daemon logs
grep CRON /var/log/syslog | tail -20
# Verify cron is running
systemctl status cron