AWS EventBridge Cron Expression: Complete 6-Field Guide With Examples
AWS EventBridge (formerly CloudWatch Events) uses a cron expression format that differs from standard Unix/Linux cron in one important way: it uses 6 fields instead of 5. This trips up almost every developer who is familiar with standard cron syntax. A valid Linux cron expression will silently fail or behave unexpectedly in EventBridge because of this difference. This guide covers the complete EventBridge cron syntax, every special character, and the most common scheduling patterns with copy-ready examples.
Build and validate EventBridge cron expressions visually with Jaconir Cron Job Generator — supports both standard 5-field and AWS 6-field formats, shows next 10 run times, and explains each expression in plain English.
EventBridge vs Standard Cron: The Key Difference
Standard cron (Unix/Linux, most job schedulers) uses 5 fields:
┌──────────── minute (0–59)
│ ┌────────── hour (0–23)
│ │ ┌──────── day-of-month (1–31)
│ │ │ ┌────── month (1–12)
│ │ │ │ ┌──── day-of-week (0–6, Sun=0)
│ │ │ │ │
* * * * *
AWS EventBridge cron uses 6 fields — year is added at the end:
┌──────────── minute (0–59)
│ ┌────────── hour (0–23)
│ │ ┌──────── day-of-month (1–31)
│ │ │ ┌────── month (1–12 or JAN–DEC)
│ │ │ │ ┌──── day-of-week (1–7 or SUN–SAT, SUN=1)
│ │ │ │ │ ┌── year (1970–2199)
│ │ │ │ │ │
* * * * * *
Two additional critical differences:
- Day-of-week numbering: Standard cron uses 0–6 (Sunday=0). EventBridge uses 1–7 (Sunday=1, Saturday=7)
- Day-of-month and day-of-week conflict: In EventBridge, you cannot specify both day-of-month and day-of-week as values simultaneously. One of them must be
?(the "no specific value" wildcard)
Field Reference
Allowed Values Per Field
| Field | Values | Wildcards |
|---|---|---|
| Minutes | 0–59 | * , - / |
| Hours | 0–23 | * , - / |
| Day-of-month | 1–31 | * , - / ? L W |
| Month | 1–12 or JAN–DEC | * , - / |
| Day-of-week | 1–7 or SUN–SAT | * , - / ? L # |
| Year | 1970–2199 | * , - / |
Special Characters
* — All values
Matches every valid value for that field.
0 12 * * ? * # Every day at 12:00 UTC
? — No specific value
Used in day-of-month or day-of-week when you are specifying the other one. Required — you cannot leave both as *.
0 9 15 * ? * # 15th of every month at 09:00 (no day-of-week constraint)
0 9 ? * MON * # Every Monday at 09:00 (no day-of-month constraint)
, — List
Specifies multiple values.
0 9 ? * MON,WED,FRI * # Monday, Wednesday, Friday at 09:00
- — Range
Specifies a range of values.
0 9-17 ? * MON-FRI * # Every hour from 09:00 to 17:00, Monday through Friday
/ — Increment
Specifies step values. start/step means "starting at start, every step."
0/15 * * * ? * # Every 15 minutes (0, 15, 30, 45)
0 0/6 * * ? * # Every 6 hours (00:00, 06:00, 12:00, 18:00)
L — Last
In day-of-month: last day of the month. In day-of-week: last occurrence of that weekday in the month.
0 18 L * ? * # Last day of every month at 18:00
0 18 ? * 6L * # Last Friday of every month at 18:00
W — Nearest weekday
In day-of-month only. Triggers on the nearest weekday (Mon–Fri) to the specified date.
0 9 15W * ? * # Nearest weekday to the 15th at 09:00
# If 15th is Saturday, fires Friday 14th
# If 15th is Sunday, fires Monday 16th
# — Nth weekday of month
In day-of-week only. Format: DAY#N = Nth occurrence of DAY in the month.
0 9 ? * 2#1 * # First Monday of every month at 09:00
0 9 ? * 6#3 * # Third Friday of every month at 09:00
0 9 ? * 1#1 * # First Sunday of every month (SUN=1 in EventBridge)
Common EventBridge Scheduling Patterns
Run Every N Minutes
# Every 5 minutes
0/5 * * * ? *
# Every 10 minutes
0/10 * * * ? *
# Every 15 minutes
0/15 * * * ? *
# Every 30 minutes
0/30 * * * ? *
Run Every Hour
# Every hour on the hour
0 * * * ? *
# Every 2 hours
0 0/2 * * ? *
# Every 6 hours
0 0/6 * * ? *
Run Once Daily
# Every day at midnight UTC
0 0 * * ? *
# Every day at 09:00 UTC
0 9 * * ? *
# Every day at 18:30 UTC
30 18 * * ? *
Run on Specific Days of the Week
# Every Monday at 08:00 UTC
0 8 ? * MON *
# Monday to Friday at 09:00 UTC (business days)
0 9 ? * MON-FRI *
# Monday, Wednesday, Friday at 12:00 UTC
0 12 ? * MON,WED,FRI *
# Weekends only at 10:00 UTC
0 10 ? * SAT,SUN *
Run on Specific Day of Month
# First of every month at 00:00 UTC
0 0 1 * ? *
# 15th of every month at 09:00 UTC
0 9 15 * ? *
# Last day of every month at 23:59 UTC
59 23 L * ? *
# First Monday of every month at 09:00 UTC
0 9 ? * MON#1 *
# Last Friday of every month at 17:00 UTC
0 17 ? * FRI L *
Run Quarterly
# First day of each quarter at 00:00 UTC (Jan, Apr, Jul, Oct)
0 0 1 1,4,7,10 ? *
Run Once a Year
# January 1st at 00:00 UTC every year
0 0 1 1 ? *
# Specific year only (one-time trigger)
0 0 1 1 ? 2026
Rate Expressions vs Cron Expressions
EventBridge supports two scheduling formats: rate and cron. Rate expressions are simpler for regular intervals:
# Rate expressions (simpler syntax for fixed intervals)
rate(5 minutes) # Every 5 minutes
rate(1 hour) # Every hour
rate(1 day) # Every 24 hours
# Cron expressions (required for specific times, days, or complex patterns)
cron(0 9 ? * MON-FRI *) # Every weekday at 09:00 — not possible with rate()
Use rate() when you want "every N units of time." Use cron() when you need a specific time of day, specific days of the week/month, or any pattern more complex than a fixed interval.
Terraform and CloudFormation Syntax
Terraform
resource "aws_cloudwatch_event_rule" "daily_job" {
name = "daily-job"
schedule_expression = "cron(0 9 ? * MON-FRI *)"
}
CloudFormation
MyScheduledRule:
Type: AWS::Events::Rule
Properties:
ScheduleExpression: "cron(0 9 ? * MON-FRI *)"
State: ENABLED
AWS CDK (TypeScript)
import { Schedule } from 'aws-cdk-lib/aws-events';
const rule = new events.Rule(this, 'DailyJob', {
schedule: Schedule.expression('cron(0 9 ? * MON-FRI *)'),
});
Common Mistakes and How to Fix Them
Mistake 1: Using 5-field cron syntax
# WRONG — standard cron, missing year field
0 9 * * 1-5
# CORRECT — EventBridge 6-field format
0 9 ? * MON-FRI *
Mistake 2: Specifying both day-of-month and day-of-week
# WRONG — both fields have values
0 9 15 * 1 *
# CORRECT — use ? for whichever you don't need
0 9 15 * ? * # 15th of month, any day-of-week
0 9 ? * MON * # Every Monday, any day-of-month
Mistake 3: Wrong day-of-week numbering
# WRONG — using standard cron numbering (Sun=0)
0 9 ? * 0 * # 0 is not valid in EventBridge day-of-week
# CORRECT — EventBridge numbering (Sun=1, Sat=7)
0 9 ? * 1 * # Sunday
0 9 ? * SUN * # Sunday (name form — clearer)
Mistake 4: Forgetting UTC
EventBridge always runs in UTC. If you need 09:00 IST (India Standard Time, UTC+5:30), set the hour to 3 and minutes to 30:
30 3 ? * MON-FRI * # 09:00 IST = 03:30 UTC
Testing Your Expression
Always verify a new EventBridge cron expression before deploying:
- Use Jaconir Cron Job Generator — enter the expression, see the next 10 scheduled run times instantly
- AWS Console → EventBridge → Rules → Create rule — the console validates the expression and shows next trigger times before you save
- The AWS CLI:
aws events put-rule --schedule-expression "cron(0 9 ? * MON-FRI *)"— returns an error immediately if the expression is invalid
FAQ
Does EventBridge support seconds in cron expressions?
No. The minimum EventBridge scheduling resolution is 1 minute. If you need sub-minute scheduling, use a Lambda function that loops internally or a different scheduler.
Can I use the same cron expression format in Hangfire?
No — Hangfire uses a 5-field standard cron format, not AWS's 6-field format. The year field is not supported in Hangfire. Remove the year field and adjust day-of-week numbering (Hangfire uses 0=Sunday).
What timezone does EventBridge use?
UTC only for cron expressions. EventBridge Scheduler (the newer service, separate from EventBridge Rules) supports timezone-aware scheduling and is the better choice if you need local time scheduling without manual UTC conversion.
What is the difference between EventBridge Rules and EventBridge Scheduler?
EventBridge Rules (the original service) uses the 6-field cron format described in this guide. EventBridge Scheduler (launched 2022) is a separate, more capable service that supports timezone-aware scheduling, flexible time windows, and higher scale. Both use cron expressions but the Scheduler also supports one-time schedules with an at() expression.
Conclusion
The 6-field EventBridge cron format catches almost everyone coming from standard cron — the added year field, the mandatory ? in day-of-month or day-of-week, and the shifted day-of-week numbering are the three mistakes that cause the most debugging time. Use the reference in this guide and validate every expression before deploying.
Build and test your EventBridge cron expression: Jaconir Cron Job Generator →