Cron expressions control when jobs run in Linux cron, GitHub Actions, Kubernetes CronJobs, AWS EventBridge, and dozens of other schedulers. The syntax is compact but not obvious — 0 9 * * 1-5 takes a moment to read without a reference. An online parser translates expressions to plain English instantly.
Parse and validate cron expressions →
Cron Expression Structure
A standard cron expression has five fields separated by spaces:
┌───────────── minute (0–59)
│ ┌───────────── hour (0–23)
│ │ ┌───────────── day of month (1–31)
│ │ │ ┌───────────── month (1–12)
│ │ │ │ ┌───────────── day of week (0–7, 0 and 7 are Sunday)
│ │ │ │ │
* * * * *
Some systems (Quartz, Spring, AWS Lambda) use a six or seven field format with seconds and/or year. The parser handles both variants.
Special Characters
| Character | Meaning | Example |
|---|---|---|
* | Any / every | * * * * * — every minute |
, | List | 1,15 * * * * — at minute 1 and 15 |
- | Range | 1-5 * * * * — minutes 1 through 5 |
/ | Step | */15 * * * * — every 15 minutes |
L | Last | 0 0 L * * — last day of month (non-standard) |
# | Nth weekday | 0 10 * * 1#2 — 2nd Monday (non-standard) |
? | No specific value | Used in day-of-month or day-of-week (Quartz) |
20 Common Cron Expressions
Every N minutes
# Every minute
* * * * *
# Every 5 minutes
*/5 * * * *
# Every 15 minutes
*/15 * * * *
# Every 30 minutes
*/30 * * * *
Hourly and daily
# Every hour (top of the hour)
0 * * * *
# Every day at midnight UTC
0 0 * * *
# Every day at 9 AM UTC
0 9 * * *
# Twice a day — 8 AM and 8 PM
0 8,20 * * *
Weekday schedules
# Every weekday at 9 AM
0 9 * * 1-5
# Every Monday at 9 AM
0 9 * * 1
# Monday, Wednesday, Friday at noon
0 12 * * 1,3,5
# Weekends at 10 AM
0 10 * * 0,6
Monthly and quarterly
# First day of every month at midnight
0 0 1 * *
# Last day of every month at 11:59 PM (standard cron)
59 23 28-31 * * (run script that checks if tomorrow is a new month)
# 1st and 15th of every month
0 0 1,15 * *
# First day of each quarter (Jan, Apr, Jul, Oct)
0 0 1 1,4,7,10 *
Specific times
# New Year's Day at midnight
0 0 1 1 *
# Every Sunday at 4 AM (maintenance window)
0 4 * * 0
# Every 6 hours
0 */6 * * *
Platform-Specific Notes
Linux crontab
Standard 5-field syntax. Run crontab -e to edit. Timezone is the system timezone.
# List current crontab
crontab -l
# Edit crontab
crontab -e
GitHub Actions
Uses the 5-field format in UTC. Note that jobs may run up to a few minutes late under load:
on:
schedule:
- cron: '0 9 * * 1-5' # weekdays at 9 AM UTC
AWS EventBridge / CloudWatch Events
Uses a 6-field format with seconds in the first position, or a separate “rate expression”:
cron(0 9 ? * MON-FRI *)
rate(5 minutes)
The ? is required in either day-of-month or day-of-week (not both).
Kubernetes CronJob
Standard 5-field syntax. The timezone field (spec.timeZone) is available in Kubernetes 1.27+:
spec:
schedule: "0 9 * * 1-5"
timeZone: "America/New_York"
Reading Cron Expressions at a Glance
Train yourself on these patterns:
- Leading
0+ hour field = “at the top of that hour” *in a field = “every unit” of that field*/n= “every n units”- Two numbers separated by
-= a range - Numbers separated by
,= a list of specific values
So 0 9 * * 1-5 reads: minute 0, hour 9, any day-of-month, any month, weekdays → 9:00 AM every weekday.
Debugging Cron Problems
Job didn’t run? Check:
- Is the cron daemon running? (
systemctl status cron) - Is the script executable? (
chmod +x script.sh) - Does the script use absolute paths? (Cron has a minimal
$PATH) - Did you save the crontab? (
crontab -lto verify) - Check logs:
/var/log/syslogor/var/log/cron
Output disappeared? Cron sends output to email by default. Redirect to a log file:
0 9 * * * /path/to/script.sh >> /var/log/myjob.log 2>&1
Timezone confusion? Cron runs in the system timezone. For explicit control, set TZ in the crontab:
TZ=America/New_York
0 9 * * 1-5 /path/to/script.sh
Validate your schedules before they hit production. Try the Cron Expression Parser →