Overview

Cron expressions describe recurring schedules as five (or six) space-separated fields. The same grammar appears in /etc/crontab, GitHub Actions schedule:, AWS EventBridge, Kubernetes CronJobs, and most task schedulers. This card covers the field grammar, special characters, common patterns, and the edge cases that cause schedules to run at the wrong time or not at all.

Field positions

Standard cron uses five fields. Some systems add a seconds field at position 0 or a year field at position 5.

FieldPositionRangeNotes
Minute1st0-590 = top of the hour
Hour2nd0-2324-hour clock, UTC unless configured otherwise
Day of month3rd1-31L for last day (some engines)
Month4th1-12 or JAN-DECMonth names are case-insensitive
Day of week5th0-7 or SUN-SAT0 and 7 both mean Sunday
Seconds0th (optional)0-59AWS, Spring, and Quartz add this before minute
Year6th (optional)1970-2099AWS EventBridge supports this

GitHub Actions uses 5-field UTC cron: on: schedule: - cron: "0 9 * * 1" runs at 09:00 UTC every Monday.

Special characters

CharacterMeaningExampleMatches
*Every value in field* * * * *Every minute
,List separator0 9,17 * * *09:00 and 17:00
-Range0 9-17 * * *Every hour 09:00 to 17:00
/Step*/15 * * * *Every 15 minutes
/ with rangeStep in range0 8-20/2 * * *Every 2 hours from 08:00 to 20:00
LLast (some engines)0 0 L * *Last day of the month at midnight
WNearest weekday (Quartz)0 0 15W * *Nearest weekday to the 15th
#Nth weekday (Quartz)0 0 * * 5#2Second Friday of the month
?No specific value (Quartz)0 0 ? * MONRequired when day-of-month and day-of-week both set

L, W, and # are extensions. Standard cron (vixie-cron, GitHub Actions) does not support them.

Common schedule patterns

ExpressionMeaning
* * * * *Every minute
0 * * * *Every hour, on the hour
0 0 * * *Daily at midnight UTC
0 9 * * *Daily at 09:00 UTC
0 9 * * 1Every Monday at 09:00
0 9 * * 1-5Weekdays at 09:00
0 9 * * 6,0Weekends at 09:00
0 0 1 * *First day of every month at midnight
0 0 1 1 *January 1st at midnight (annual)
*/5 * * * *Every 5 minutes
*/15 9-17 * * 1-5Every 15 min during business hours on weekdays
0 0,12 * * *Twice daily: midnight and noon
@rebootAt system startup (vixie-cron only)
@hourlySame as 0 * * * *
@dailySame as 0 0 * * *
@weeklySame as 0 0 * * 0
@monthlySame as 0 0 1 * *

Use https://crontab.guru to verify expressions interactively.

Timezone handling

Most cron daemons run in the system timezone or UTC. Timezone mismatches are the most common source of “wrong time” bugs.

SystemTimezone defaultHow to change
vixie-cron (Linux)System timezoneCRON_TZ=America/New_York line in crontab
crontab -eSystem timezoneCRON_TZ= or TZ= at top of file
GitHub ActionsUTC alwaysConvert local time to UTC before writing expression
AWS EventBridgeUTCSet timezone in the EventBridge rule (separate field)
Kubernetes CronJobUTCSet spec.timeZone: "America/New_York" (k8s 1.27+)

A job scheduled for 0 9 * * * on a UTC system runs at 09:00 UTC, which is 04:00 EST in winter and 05:00 EDT in summer.

Validation and testing

ToolPurpose
crontab -lList current user’s crontab
crontab -eEdit current user’s crontab
/var/log/syslog or journalctl -u cronView cron execution log
run-onePrevent overlapping runs of the same job
flock -n /tmp/job.lock cmdAdvisory lock to prevent overlap
crontab.guruWeb expression validator

Common gotchas

  • Day-of-week and day-of-month are OR’d in vixie-cron: 0 0 1 * 1 fires on the 1st of the month OR every Monday, not the intersection. Use a script check if you need AND logic.
  • The */n step always starts at 0 (or 1 for DOM): */7 means 0, 7, 14, 21, 28, 35, 42, 49, 56, not evenly spaced seven-minute slots.
  • Environment variables in crontabs are minimal. PATH, HOME, and SHELL are set; your login shell’s ~/.bashrc is not sourced. Use absolute paths for binaries.
  • Output not redirected to a file is mailed to the local user via sendmail. On servers without a mail daemon, this fills /var/spool/mail. Add >/dev/null 2>&1 to suppress.
  • GitHub Actions schedule events are queued, not guaranteed. During high load, runs can be delayed by minutes or hours. Do not rely on sub-minute precision.