skip to content

Why would you use Amazon EventBridge Scheduler instead of a scheduled EventBridge rule (a cron rule on an event bus)?

level: middleimportance: should knowfreq 52%

answer

  1. rules react to events, Scheduler only to time
  2. quota is per schedule, not per job
  3. one-time schedules that self-delete
  4. every schedule brings its own role
  5. jitter the herd with a window

basics

~20 s

EventBridge Scheduler is a separate service built for scale and per-entity timers: one-time schedules, a far higher schedule quota, a per-schedule IAM role, retry and dead-letter settings per schedule, time-zone support, and flexible time windows that spread invocations.

solid answer

~50 s

A scheduled rule lives on an event bus and shares the bus's rule quota, which is in the hundreds — fine for a handful of platform-wide jobs, useless for one timer per customer. Scheduler is a standalone service designed for the second case: it supports one-time `at()` schedules that can delete themselves, its schedule quota is orders of magnitude larger, and each schedule carries its own IAM role, retry policy and dead-letter queue instead of inheriting bus-level configuration. It also adds things rules never had — an explicit time-zone setting so cron follows local wall clock through daylight saving, start and end dates, schedule groups for tagging and organising, and a flexible time window that jitters invocations across a range so ten thousand schedules do not all fire on the same second. Rules still make sense when the schedule is one of several targets on a bus you already operate.

code

bash · 6 lines
bash
aws scheduler create-schedule --name tenant-42-digest \
  --group-name tenant-digests \
  --schedule-expression "cron(0 8 ? * MON-FRI *)" \
  --schedule-expression-timezone "Europe/Berlin" \
  --flexible-time-window "Mode=FLEXIBLE,MaximumWindowInMinutes=15" \
  --target '{"Arn":"arn:aws:lambda:eu-central-1:111122223333:function:send-digest","RoleArn":"arn:aws:iam::111122223333:role/scheduler-tenant-42","Input":"{\"tenantId\":42}","RetryPolicy":{"MaximumRetryAttempts":3,"MaximumEventAgeInSeconds":3600},"DeadLetterConfig":{"Arn":"arn:aws:sqs:eu-central-1:111122223333:digest-dlq"}}'

go deeper

for a junior

Know that EventBridge Scheduler is a separate service for time-based invocations and that it can fire once at a timestamp, which a scheduled rule cannot. Name Lambda and Step Functions as typical targets.

for a middle

Contrast the two on quota, one-time schedules, per-schedule IAM role, and per-schedule retry and dead-letter settings. Explain why per-customer timers are a Scheduler design and not a rules design.

for a senior

Demonstrate operating it: flexible time windows to flatten a midnight spike, time zones so business jobs survive daylight saving, and a cleanup story so completed one-time schedules do not exhaust the quota.

for a principal

Own the platform decision — when a per-entity timer service beats a durable-workflow or database-driven approach, how schedule sprawl is attributed and cleaned up per tenant, and what blast radius a shared scheduler role would create.

## Two different problems EventBridge rules gained cron support as an extension of a pattern-matching service: a rule normally matches events, and a *scheduled* rule matches the clock instead. That works, and for the ten platform jobs a team runs it is still perfectly reasonable. EventBridge Scheduler was built for the case rules were never shaped for — **per-entity timers**, where the number of schedules tracks the number of customers, orders or reservations rather than the number of jobs. ## What Scheduler adds **Scale.** Scheduled rules consume the rule quota on the event bus they live on, which is in the hundreds by default — so "one rule per customer" hits a wall almost immediately. Scheduler's default schedules-per-account quota is in the millions (check Service Quotas for the current value in your region, as these change), which makes one-schedule-per-entity a legitimate design rather than a hack. **One-time schedules.** A rule is recurring; there is no "fire once" rule. Scheduler's `at(2026-03-01T09:00:00)` fires exactly once, and `ActionAfterCompletion=DELETE` makes it clean itself up afterwards. Without that setting a fired schedule lingers in a completed state and still counts against the quota. **Per-schedule identity.** Each schedule specifies its own `RoleArn`, which Scheduler assumes to invoke the target. That is a real security improvement: the schedule that expires *this* tenant's hold can be given a role scoped to that tenant's resources, instead of every scheduled job sharing whatever the bus-level target configuration allows. **Per-schedule reliability settings.** A schedule carries its own `RetryPolicy` (`MaximumRetryAttempts` and `MaximumEventAgeInSeconds`) and its own `DeadLetterConfig` pointing at an SQS queue. A schedule whose target is down retries on its own terms and lands its failed invocation somewhere you can inspect and redrive. **Time zones and windows.** `ScheduleExpressionTimezone` takes an IANA zone name so a cron schedule follows local wall-clock time across daylight-saving transitions. `StartDate` and `EndDate` bound the active period. And `FlexibleTimeWindow` — set to `FLEXIBLE` with a `MaximumWindowInMinutes` — lets Scheduler pick a moment within that window instead of the exact instant. ```json { "FlexibleTimeWindow": { "Mode": "FLEXIBLE", "MaximumWindowInMinutes": 15 }, "ScheduleExpressionTimezone": "Europe/Berlin" } ``` That window is the answer to the midnight stampede: without it, every daily schedule set to 00:00 fires simultaneously and your downstream sees a spike it must be provisioned for. With a fifteen-minute window, the same work is spread and the peak flattens. The tradeoff is explicit — you are trading precision for smoothness, so it belongs on maintenance jobs, not on anything with a contractual firing time. **Universal targets.** Beyond the templated targets, Scheduler can call a very large set of AWS SDK actions directly, so many schedules need no Lambda at all — the schedule itself performs the API call, using its role. **Schedule groups.** Schedules are organised into groups, which is where tagging and bulk management happen. It is a small thing until you have half a million schedules and need to attribute cost or delete a tenant's timers. ## What Scheduler does not do Scheduler only handles time. It does not match event patterns, it has no bus, no archive, no replay, and it does not fan out to multiple targets from a single schedule the way a rule can carry several targets. If your requirement is "when this event happens, do these three things", that is still buses and rules. If it is "at this moment, do this one thing", that is Scheduler. ## The interview answer The crisp framing: *rules are for reacting to events, with clock-based rules as a convenience; Scheduler is a purpose-built timer service whose unit of scale is the schedule, not the job.* Then name the three differences that actually decide a design — one-time schedules, the quota that permits per-entity timers, and the per-schedule role, retry policy and DLQ. Mention the flexible time window as the operational detail that shows you have run this at scale.

  • What problem does the flexible time window solve?
    A thundering herd. Set `FlexibleTimeWindow` to `FLEXIBLE` with a `MaximumWindowInMinutes` and Scheduler picks an invocation moment inside that window instead of the exact instant, spreading thousands of midnight schedules over minutes. You trade precision for a flatter downstream peak, so use it for maintenance work, not contractual timings.
  • How does a schedule get permission to invoke its target?
    Each schedule specifies a `RoleArn` that Scheduler assumes to make the call, so permissions are scoped per schedule rather than shared. The role's trust policy must allow the Scheduler service principal, and it is good practice to constrain it with `aws:SourceArn` so only that schedule can use it.
  • Is there anything a scheduled rule does that Scheduler cannot?
    Rules live on a bus, so a single rule can carry several targets and sits alongside your pattern-matched rules with the same archive, replay and monitoring story. Scheduler has one target per schedule and no notion of events at all. For a small number of fan-out platform jobs on a bus you already run, a rule is still simpler.

saying these in an interview costs you the question

  • Says Scheduler and scheduled rules are the same feature renamed
  • Plans one scheduled rule per customer
  • Assumes all schedules share one execution role
  • Thinks Scheduler can match event patterns
  • Ignores that fired one-time schedules persist by default

context