Cron Syntax Complete Guide: Expressions, Patterns, and Timezone Gotchas
Master cron expression syntax, understand common scheduling patterns, and avoid the timezone pitfalls that cause production incidents.
Cron Syntax Complete Guide: Expressions, Patterns, and Timezone Gotchas
Cron is the de facto scheduler for Unix systems and has been adopted by cloud platforms, CI/CD pipelines, and job queues worldwide. The syntax looks cryptic at first glance but follows a consistent logic. Master it once and you'll read cron expressions as naturally as reading a clock.
The Five (or Six) Field Format
A standard cron expression has five fields:
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12 or JAN-DEC)
│ │ │ │ ┌───────────── day of week (0-7, 0 and 7 are Sunday)
│ │ │ │ │
* * * * *
Many modern schedulers (Kubernetes CronJobs, GitHub Actions, AWS EventBridge) support a sixth field for seconds:
┌──────────────── second (0-59)
│ ┌──────────────── minute (0-59)
│ │ ...
* * * * * *
Field Values and Special Characters
| Character | Meaning | Example |
|---|---|---|
* |
Every value | * * * * * = every minute |
, |
Value list | 1,15,30 = at minutes 1, 15, and 30 |
- |
Range | 9-17 = from hour 9 through 17 |
/ |
Step | */5 = every 5 units; 10/5 = 10, 15, 20... |
L |
Last | L in day-of-month = last day of the month |
W |
Nearest weekday | 15W = nearest weekday to the 15th |
# |
Nth weekday | 2#3 = third Monday of the month |
Common Cron Schedule Patterns
# Every minute
* * * * *
# Every 5 minutes
*/5 * * * *
# Every hour, on the hour
0 * * * *
# Daily at midnight
0 0 * * *
# Daily at 2:30 AM
30 2 * * *
# Every weekday (Mon-Fri) at 9 AM
0 9 * * 1-5
# First day of every month at midnight
0 0 1 * *
# Every 15 minutes during business hours
*/15 9-17 * * 1-5
# Every Sunday at 3 AM (common for backups)
0 3 * * 0
# Quarterly: Jan 1, Apr 1, Jul 1, Oct 1 at midnight
0 0 1 1,4,7,10 *
Timezone Gotchas
This is where most cron-related production incidents originate.
System Timezone vs. Application Timezone
Cron reads the system timezone by default. If your server is in UTC but your stakeholders expect "midnight EST" execution, the schedule needs adjustment:
# Midnight EST (UTC-5) expressed in UTC
0 5 * * *
# Midnight EDT (UTC-4) expressed in UTC (during daylight saving)
0 4 * * *
The problem: DST transitions cause your job to shift by one hour unless you configure timezone-aware scheduling.
Kubernetes CronJob Timezone
Kubernetes added timezone support in v1.27 via the spec.timeZone field:
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-report
spec:
schedule: "0 8 * * *"
timeZone: "America/New_York"
Without timeZone, the schedule runs in the cluster timezone (usually UTC). With it, you get DST-aware scheduling.
AWS EventBridge Scheduler
EventBridge Scheduler supports IANA timezone strings in its cron expressions, making DST handling automatic:
cron(0 8 * * ? *) in timezone America/Chicago
Note: AWS cron syntax replaces day-of-week with ? (no specific value) when day-of-month is set, and vice versa. Both cannot be set to * simultaneously.
Day-of-Week Numbering
One subtle inconsistency: in standard cron, Sunday is both 0 and 7. In some systems (Quartz Scheduler), Sunday is 1 and Saturday is 7. Always verify which convention your platform uses.
Debugging Cron Expressions
Common questions when debugging:
- "Why didn't my job run?" — Check the system log (
/var/log/syslog,/var/log/cron) and verify the cron daemon is running. - "Why did it run at the wrong time?" — Check timezone configuration and DST offset.
- "Why is it running more often than expected?" — A
*/1field matches every unit; double-check step syntax.
Humanize Your Cron Expressions
Before deploying a cron schedule, verify it says what you think it says. The Cron Humanizer on InfraHub translates cron expressions into plain English, shows the next 10 scheduled run times, and flags potential issues like conflicting day-of-month and day-of-week fields. It runs entirely in your browser.
Paste in 0 0 */7 * * and confirm whether it actually runs on the 7th, 14th, 21st, and 28th of the month — or something else entirely.