bitlvl
EN

Cron cheat sheet

Field order, the schedules people actually need, and the three gotchas that account for most “my cron job doesn’t run” tickets.

Fits on one A4 / Letter page in portrait; use “Save as PDF” in the print dialog to keep a copy.

Syntax

┌─ minute (0–59)
│ ┌─ hour (0–23)
│ │ ┌─ day of month (1–31)
│ │ │ ┌─ month (1–12, jan–dec)
│ │ │ │ ┌─ weekday (0–7, sun–sat; 0 and 7 = Sunday)
* * * * *  command
*every value
5exactly 5
1-5range
*/15every 15th
1,15list
8-18/2step within range

Special strings

@rebootonce at boot
@hourly0 * * * *
@daily / @midnight0 0 * * *
@weekly0 0 * * 0
@monthly0 0 1 * *
@yearly / @annually0 0 1 1 *

Schedules

* * * * *every minute
*/5 * * * *every 5 minutes
*/15 9-17 * * 1-5every 15 min, working hours, weekdays
0 * * * *hourly, on the hour
30 * * * *hourly at :30
0 */6 * * *every 6 hours (0, 6, 12, 18)
0 0 * * *daily at midnight
0 3 * * *daily at 03:00
30 6 * * 1-5weekdays at 06:30
0 9,17 * * 1-5weekdays at 09:00 and 17:00
0 0 * * 0Sundays at midnight
0 0 * * 6,0weekends
0 0 1 * *first of the month
0 0 1,15 * *1st and 15th
0 0 1 */3 *quarterly (Jan, Apr, Jul, Oct 1st)
0 0 1 1 *yearly
0 0 * * 1#1first Monday (non-standard; use 0 0 1-7 * 1)
0 0 1-7 * 1first Monday — beware: fires on days 1–7 OR any Monday; add [ $(date +\%u) = 1 ] test
0 0 28-31 * * [ $(date -d tomorrow +\%d) = 01 ] && cmdlast day of the month
0 2 * * * sleep $((RANDOM \% 1800)); cmd02:00 with up to 30 min jitter

Gotchas

  • PATH is minimal (/usr/bin:/bin). Use absolute paths or set PATH=… at the top of the crontab.
  • % means newline in the command; write \% (date +\%F).
  • No shell profile: aliases, nvm, rbenv, venvs are not loaded.
  • Time zone is the daemon's (usually the system's, often UTC on servers). CRON_TZ=Europe/Belgrade works in cronie.
  • Day-of-month AND weekday both set = runs when either matches.
  • Output is mailed to the user; redirect it or set MAILTO=.
  • Overlap: cron starts the job again even if the last one is still running. Wrap in flock -n /tmp/job.lock cmd.

Commands

crontab -eedit your crontab
crontab -llist
crontab -rremove all (no confirmation!)
crontab -u www-data -lanother user's (root)
/etc/crontab, /etc/cron.d/*system crontabs: have a user field after the schedule
/etc/cron.{hourly,daily,weekly,monthly}/drop-in scripts, run by anacron on desktops
grep CRON /var/log/syslog; journalctl -u cronsee what ran

A safe template

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
[email protected]
SHELL=/bin/bash
# m h dom mon dow  command
30 6 * * 1-5  flock -n /run/backup.lock /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Questions

How do I check what a cron expression means?

Paste it into the cron explainer; it prints the schedule in English and the next ten run times in your time zone.