Cron Expression Examples: Syntax, Patterns, and Common Schedules
A practical reference for cron expressions - how each field works, the special characters that make cron flexible, and real-world schedule examples you can copy directly.
Cron is the original Unix job scheduler. Despite being decades old, it’s still the backbone of scheduled tasks in Linux servers, CI/CD pipelines, Kubernetes CronJobs, and cloud functions. The expression syntax is compact and expressive once you know what each part means.
Cron expression format
A standard cron expression has five fields:
┌───────────── minute (0–59)
│ ┌───────────── hour (0–23)
│ │ ┌───────────── day of month (1–31)
│ │ │ ┌───────────── month (1–12)
│ │ │ │ ┌───────────── day of week (0–7, where 0 and 7 are Sunday)
│ │ │ │ │
* * * * *
Each field accepts numbers, ranges, lists, step values, or the wildcard *.
Field values
| Field | Range | Special values |
|---|---|---|
| Minute | 0–59 | *, ,, -, / |
| Hour | 0–23 | *, ,, -, / |
| Day of month | 1–31 | *, ,, -, /, L, W |
| Month | 1–12 or JAN–DEC | *, ,, -, / |
| Day of week | 0–7 (0=Sun, 7=Sun) | *, ,, -, /, L, # |
Special characters
* - Wildcard
Matches every value in the field.
* * * * * # Every minute
0 * * * * # Every hour, at minute 0
, - List
Runs at multiple specific values.
0 9,17 * * * # At 9:00 AM and 5:00 PM
0 0 1,15 * * # At midnight on the 1st and 15th of each month
- - Range
Runs for every value in a continuous range.
0 9-17 * * * # Every hour from 9 AM to 5 PM
0 0 * * 1-5 # Midnight on weekdays (Mon–Fri)
/ - Step
Runs every N units within a range. */5 means “every 5.”
*/5 * * * * # Every 5 minutes
0 */2 * * * # Every 2 hours
0 0 */7 * * # Every 7 days (approximately weekly)
L - Last (day of month / day of week)
Available in many extended cron implementations.
0 0 L * * # Last day of the month at midnight
0 0 * * 5L # Last Friday of the month
# - Nth weekday
0 10 * * 1#2 # Second Monday of the month at 10 AM
Common cron schedule examples
Time-based schedules
# Every minute
* * * * *
# Every 5 minutes
*/5 * * * *
# Every 15 minutes
*/15 * * * *
# Every 30 minutes
*/30 * * * *
# Once an hour (at minute 0)
0 * * * *
# Every 6 hours
0 */6 * * *
# Once a day at midnight UTC
0 0 * * *
# Once a day at 9 AM
0 9 * * *
# Twice a day (6 AM and 6 PM)
0 6,18 * * *
Day-based schedules
# Every Monday at 8 AM
0 8 * * 1
# Weekdays only, at 9 AM
0 9 * * 1-5
# Weekends only, at 10 AM
0 10 * * 6,0
# Every Sunday at midnight
0 0 * * 0
Month-based schedules
# First day of every month at midnight
0 0 1 * *
# Last day of every month at 11:59 PM (closest without L)
59 23 28-31 * *
# First Monday of every month at 9 AM
0 9 * * 1#1
# Every quarter (Jan, Apr, Jul, Oct) on the 1st
0 0 1 1,4,7,10 *
# Once a year on January 1st at midnight
0 0 1 1 *
Business / working hours
# Every 30 minutes during business hours on weekdays
*/30 9-17 * * 1-5
# Every hour from 8 AM to 10 PM
0 8-22 * * *
# Daily report at 6 AM on weekdays
0 6 * * 1-5
Quick reference table
| Schedule | Expression |
|---|---|
| Every minute | * * * * * |
| Every 5 minutes | */5 * * * * |
| Every hour | 0 * * * * |
| Every day at midnight | 0 0 * * * |
| Every Monday at 8 AM | 0 8 * * 1 |
| Weekdays at 9 AM | 0 9 * * 1-5 |
| 1st of every month | 0 0 1 * * |
| Every Sunday midnight | 0 0 * * 0 |
| Every 15 min, 9–5 weekdays | */15 9-17 * * 1-5 |
| Twice daily (6 AM + 6 PM) | 0 6,18 * * * |
Extended cron with seconds
Some tools (AWS EventBridge, Quartz, GitHub Actions) use a 6-field format with seconds as the first field:
# AWS EventBridge / Quartz: second minute hour day month weekday
0 */5 * * * ? # Every 5 minutes (AWS format - ? means "any")
0 0 9 * * MON # Every Monday at 9 AM (Quartz format)
GitHub Actions uses a 5-field standard cron in schedule.cron - no seconds field.
Testing cron expressions
Before deploying a schedule, verify it produces the times you expect. Use the ByteKiwi Cron Generator to:
- Build an expression visually from sliders and dropdowns
- See the next 5–10 scheduled run times
- Convert between human language (“every weekday at 9 AM”) and cron syntax
Common gotchas
Day of month vs day of week interaction
When you specify both day-of-month and day-of-week (neither is *), most cron implementations treat them as an OR, not AND:
0 0 1 * 1 # Midnight on the 1st of the month OR every Monday
# NOT: midnight on Mondays that fall on the 1st
Month numbering
Months are 1-indexed (1 = January, 12 = December). Some implementations also accept 3-letter names: JAN, FEB, …, DEC.
Sunday is 0 or 7
Day of week accepts both 0 and 7 for Sunday. 1 is always Monday. This avoids the fence-post confusion common in older implementations.
Missed jobs when the system is offline
Standard cron does not run missed jobs when the system restarts. If your task must run exactly once (like a billing batch), use a tool that supports job persistence or idempotency checks.
Cron in CI/CD and cloud
| Platform | Syntax | Notes |
|---|---|---|
| GitHub Actions | 5-field standard | Minimum interval: 5 minutes |
| AWS EventBridge | 5-field + 6-field | Uses ? instead of * for “any” |
| Kubernetes CronJob | 5-field standard | Supports timeZone field |
| Linux crontab | 5-field standard | Per-user and /etc/cron.d/ |
| Heroku Scheduler | Predefined intervals | No custom cron syntax |
FAQ
How do I run a cron job every 2 hours?
Use the step operator: 0 */2 * * *. This runs at 00:00, 02:00, 04:00, and so on. If you want it to start at a specific hour like 1 AM, use 0 1-23/2 * * * (runs at 1, 3, 5, …, 23).
Can cron run a job every 30 seconds?
Standard 5-field cron only goes down to 1-minute resolution. For sub-minute schedules, you need an alternative: run a job every minute that loops internally, or use a tool like systemd timers, Kubernetes with a higher-frequency scheduler, or a message queue.
What does @reboot mean in cron?
@reboot is a special macro supported by most cron implementations that runs the job once when the system starts. Other macros include @hourly, @daily, @weekly, and @monthly.
How do I see the next run times for a cron expression?
The Cron Generator shows upcoming run times. You can also use the cronitor describe CLI or libraries like cron-parser in Node.js:
import { parseExpression } from 'cron-parser';
const interval = parseExpression('*/15 9-17 * * 1-5');
for (let i = 0; i < 5; i++) {
console.log(interval.next().toDate());
}
Is there a difference between 0 0 * * * and @daily?
No - @daily (and its alias @midnight) is shorthand for 0 0 * * *. Both run once per day at midnight. Use whichever is clearer to your team.