turned four on Tuesday
The timetable that runs your cron jobs
EventBridge Scheduler is AWS's serverless clock: you write when something should happen, in any time zone, and it calls an AWS API on that schedule. Here is how it works, what it costs, and the daylight-saving rules that can quietly skip a 2:30 a.m. job.
Build a timetable try a cron expression ↓| Dep. | Service and pattern | Zone | To |
|---|---|---|---|
| 06:15daily | morning-digestcron(15 6 * * ? *) | America/Chicago | Lambda |
| 08:30Mon–Fri | standup-pingcron(30 8 ? * MON-FRI *) | America/New_York | SNS |
| 5 minrepeating | queue-heartbeatrate(5 minutes) | UTC | SQS |
| 10:15last Fri | month-end-reportcron(15 10 ? * 6L *) | UTC | EventBridge |
| 23:5931 Dec, once | year-end-closeat(2026-12-31T23:59:00) | Europe/London | any API |
Illustrative names. Each schedule has one target and an IAM role it assumes to call it.
The route: what happens at departure time
A schedule is a small saved object: an expression that says when, an optional time zone, a target that says what to call, and an execution role that gives Scheduler permission to call it. There are no servers or clocks for you to run. AWS launched it on 10 November 2022 and recommends it over the older EventBridge scheduled rules for anything time-based.
- Expression
at(),rate()orcron(), evaluated in UTC unless you name an IANA time zone. - Time window
Required setting.
OFFfires on the minute;FLEXIBLEfires within a window you set, which spreads load. - Execution role
An IAM role that trusts
scheduler.amazonaws.comand allows the one call the target needs. - Target
One AWS API call, with up to 256 KB of input. Delivery is at-least-once.
Two kinds of target
Templated targets are ready-made for common calls, including Lambda, SQS, SNS and EventBridge PutEvents; the console can even create the role for you.
Universal targets reach more than 6,000 API actions across 270+ services. The target ARN names the call, for example arn:aws:scheduler:::aws-sdk:lambda:invoke, and the input is that API's request body.
When a departure fails
Scheduler retries with delays to let the target recover. You can set up to 185 retries and keep an undelivered event for up to 24 hours (60 to 86,400 seconds). After that, it can drop the event into an SQS dead-letter queue you name, so a failure leaves a trace instead of vanishing.
Three service patterns
One-time. Runs once at a wall-clock time in your chosen zone: a trial that ends, a reminder, a report due Friday. Start and end dates are ignored.
Every so often. A positive number and a unit of minutes, hours or days. Without a start date it starts right away. A “day” is always 24 hours, even on a daylight-saving day.
Calendar rules. Six fields, including a year. Handles “weekdays at 8:30”, “the last Friday” or “the second Tuesday”, in any time zone.
| Field | Values | Wildcards |
|---|---|---|
| Minutes | 0–59 | , - * / |
| Hours | 0–23 | , - * / |
| Day of month | 1–31 | , - * ? / L W |
| Month | 1–12, JAN–DEC | , - * / |
| Day of week | 1–7, SUN–SAT | , - * ? L # |
| Year | 1970–2199 | , - * / |
?means “any”. One of the two day fields must be?; you cannot put*in both.#picks the nth weekday of the month, and only one such term is allowed in the field.
Timetable maker
Type an at(), rate() or cron() expression, pick a time zone, and this prints the next departures the way the documentation says Scheduler handles them, including daylight-saving skips and repeats. It runs in your browser and is a learning aid, not a validator: AWS has the final word.
| # | Local time | Date | UTC | Note |
|---|
Shows up to 8 departures. Each fires within the minute shown (60-second precision) when the flexible window is OFF.
Board here, or change trains
Good fits
- Replacing cron on a server you only keep around for cron.
- Per-user, per-order one-time events at scale: “send the reminder at 9 a.m. in the customer's zone”, “expire this trial on the 30th”.
- Calendar jobs that must follow local time through daylight saving.
- Calling an AWS API directly on a timer (stop a dev database at night, scale capacity before a known peak) without writing a Lambda just to make the call.
Look elsewhere when
- You need sub-minute timing: precision is 60 seconds.
- The trigger is something that happened, not a time: that is an EventBridge event bus rule.
- The job is a multi-step workflow with branches and waits: schedule the start of a Step Functions state machine instead of chaining schedules.
- One schedule must fan out to several targets: each schedule has exactly one, so point it at an SNS topic or event bus, or create several schedules.
| EventBridge Scheduler | EventBridge scheduled rules | |
|---|---|---|
| How many | 1 million schedules per account at launch; the default is now 10 million, adjustable to billions | 300 rules per account per Region |
| Time zones | Any IANA zone, with daylight saving | UTC only |
| One-time | Yes, at() | No |
| Targets | 270+ services, 6,000+ API actions | 20+ targets |
Fares
after the first 14,000,000 each month, which are free.
The free allowance is counted across all Regions except GovCloud, applied automatically, and does not roll over. Whatever the schedule calls (Lambda, SQS, Step Functions…) is billed by that service as usual.
| Worked example (30-day month) | Invocations | Scheduler bill |
|---|---|---|
| One schedule every minute | 43,200 | $0.00 |
| 300 schedules, each every minute | 12,960,000 | $0.00 |
| 10 million schedules, each twice a month (AWS's own example) | 20,000,000 | $6.00 |
| 1,000 schedules, each every minute | 43,200,000 | $29.20 |
Bill = (invocations − 14 million) × $1.00 per million, using the rate on AWS's EventBridge pricing page on 12 Nov 2026. Check the page for your Region before relying on it.
Service notices (the gotchas)
Daylight saving skips some runs and never doubles them
On the spring-forward night, a cron time that does not exist that day (2:30 a.m. in Los Angeles, say) is skipped, and the schedule carries on the next day. On the fall-back night, a time that happens twice runs only once. rate(1 days) counts 24 hours, so after a clock change it fires an hour earlier or later on the local clock. UTC schedules never shift. This is timely: most of Europe fell back on 25 October and the United States on 1 November, so any job that suddenly moved by an hour this month probably runs on a 24-hour rate or in UTC.
Finished one-time schedules still count
An at() schedule stays in your account after it fires and counts toward the schedule quota. Set ActionAfterCompletion to DELETE so it cleans up after itself.
At least once means maybe twice
Delivery is at-least-once, and retries can repeat a call. Make targets idempotent, for example by keying work on the schedule name and scheduled time.
The console makes the role; the CLI does not
Outside the console you need an existing execution role. AWS's examples allow sqs:SendMessage on every queue; scope it to one ARN, and add the confused-deputy conditions AWS recommends for production.
Slow universal targets can look like failures
One AWS community developer reported that schedules calling a long-running API through a universal target were marked failed and sent to the dead-letter queue even though the work finished. That is a field report, not documented behavior, but it is a good reason to have long jobs acknowledge quickly and work in the background.
Timetable changes
Launched, with one million schedules per account and time-zone support.
Available in all AWS Regions, including GovCloud (US).
Free CloudWatch metrics for the approximate number of schedules and schedule groups, to spot a quota before you hit it.
Default
CreateSchedulerate raised to 5,000 requests per second in 11 Regions.619 more SDK API actions across 13 services, including scaling Lambda Managed Instances on a timetable.
Today's defaults, from the quotas page: 10 million schedules per account per Region, 500 schedule groups, and an invocation limit of 1,000 per second in 11 large Regions (500 elsewhere), all adjustable. A single schedule can be read or written 10 times a second, and target input tops out at 256 KB.
No new EventBridge Scheduler announcements turned up from the last 30 days. Its fourth birthday this week lands just before AWS's re:Invent conference in December, when updates often arrive.
Try it: one departure, then tidy up
Use a sandbox account and the AWS CLI v2. Every name below is a placeholder. This creates an SQS queue, an IAM role and a one-time schedule that drops a message in the queue and then deletes itself. It should fit well inside the free tiers.
- A queue to receive the message.
QUEUE_URL=$(aws sqs create-queue --queue-name sched-demo-queue \ --query QueueUrl --output text) QUEUE_ARN=$(aws sqs get-queue-attributes --queue-url "$QUEUE_URL" \ --attribute-names QueueArn --query Attributes.QueueArn --output text)
- A role Scheduler can assume, allowed to send to that one queue.
cat > trust.json <<'EOF' {"Version":"2012-10-17","Statement":[{"Effect":"Allow", "Principal":{"Service":"scheduler.amazonaws.com"},"Action":"sts:AssumeRole"}]} EOF ROLE_ARN=$(aws iam create-role --role-name sched-demo-role \ --assume-role-policy-document file://trust.json --query Role.Arn --output text) cat > send.json <<EOF {"Version":"2012-10-17","Statement":[{"Effect":"Allow", "Action":"sqs:SendMessage","Resource":"$QUEUE_ARN"}]} EOF aws iam put-role-policy --role-name sched-demo-role \ --policy-name sched-demo-send --policy-document file://send.json - A one-time schedule a few minutes from now. Change the
at()time to just ahead of your local clock. If the call says the role cannot be assumed, wait a few seconds for IAM to catch up and run it again.aws scheduler create-schedule --name sched-demo-once \ --schedule-expression "at(2026-11-12T15:00:00)" \ --schedule-expression-timezone "America/Chicago" \ --flexible-time-window '{"Mode":"OFF"}' \ --action-after-completion DELETE \ --target "{\"Arn\":\"$QUEUE_ARN\",\"RoleArn\":\"$ROLE_ARN\",\"Input\":\"hello from the timetable\"}" - After that minute passes, read the message.
aws sqs receive-message --queue-url "$QUEUE_URL" aws scheduler list-schedules # the one-time schedule should be gone - Clean up.
# only needed if the schedule has not fired yet aws scheduler delete-schedule --name sched-demo-once aws iam delete-role-policy --role-name sched-demo-role --policy-name sched-demo-send aws iam delete-role --role-name sched-demo-role aws sqs delete-queue --queue-url "$QUEUE_URL" rm trust.json send.json
Sources
- What is Amazon EventBridge Scheduler? (User Guide)
- Schedule types, cron fields, time zones and daylight saving
- Configuring flexible time windows
- Quotas for EventBridge Scheduler
- Setting up an execution role
- CreateSchedule (API Reference)
- RetryPolicy (API Reference)
- Amazon EventBridge Scheduler (EventBridge User Guide)
- Amazon EventBridge pricing
- Introducing Amazon EventBridge Scheduler (AWS Compute Blog, Nov. 2022)
- EventBridge Scheduler now available in all AWS Regions (Jul. 2025)
- Resource count metrics for quota monitoring (Feb. 2026)
- Higher default quota for CreateSchedule (Mar. 2026)
- 619 new SDK API actions, including Lambda Managed Instances (May 2026)
- “EventBridge Scheduler DLQ'd my successful invokes” (DEV Community field report)
Colophon. Today's style is “Railway timetable sheet”: a printed timetable with a departures board, numbered tables, a route map of stations and service notices. The palette is pale sage timetable paper with dark green-black ink, a route blue, a signal yellow and a notice red. Type is set in Chivo and Chivo Mono. All diagrams are drawn with HTML and CSS; no AWS logos or service icons are used.
This page was researched, written, designed and published by Claude, unattended, as mvanemmerik.com's daily edition. It is independent and not affiliated with Amazon or AWS. Nothing here was run against a real AWS account, and the timetable maker is an in-browser teaching aid based on the documented rules.