Cron Jobs on AWS
A scheduled job (cron job) is a task that runs automatically at a fixed time or on a recurring interval — no incoming request triggers it. Common uses include sending digest emails, archiving old records, generating reports, polling external APIs, and running database clean-up. On AWS the canonical service for this is EventBridge Scheduler.
Overview
Scheduled jobs sit outside the normal request/response flow. Because nothing is waiting for a response, they can be slow, retried on failure, and run off-peak without affecting users. The key design concerns are:
- Idempotency — at-least-once delivery means a job can fire more than once for the same schedule slot (network retries, delivery guarantees). Design the job so running it twice produces the same result as running it once.
- Missed schedules — if the target is unavailable when the schedule fires, the invocation is lost by default. Use a dead-letter queue (DLQ) and a retry policy to capture and replay failures.
- Clock skew — AWS schedules are evaluated in UTC. If your cron expression encodes a business rule that depends on local time (e.g. "9 AM New York"), account for DST transitions explicitly or use a flexible time window.
- Overlapping runs — a long-running job started at T may still be running when the next invocation fires at T+interval. Either ensure the job completes well within the interval, or use a lock (DynamoDB conditional write, Redis
SET NX) to skip the second invocation if the first is still running.
EventBridge Scheduler
EventBridge Scheduler is a dedicated AWS scheduling service (launched November 2022) that invokes a target directly — no event bus in between. It supports one-time and recurring schedules, flexible time windows, retry policies, and DLQ integration.
Core concepts
- Schedule — the resource you create. It holds the expression, the target, and the retry/DLQ configuration. Schedules are regional.
- Target — what to invoke. Supports over 270 AWS API operations directly (Lambda
Invoke, ECSRunTask, Step FunctionsStartExecution, SQSSendMessage, SNSPublish, and more). You provide the ARN and an IAM role the scheduler assumes. - Flexible time window — instead of firing at exactly T, the scheduler picks a random time within a window (e.g. within 15 minutes of T). Useful for spreading load when thousands of schedules would otherwise all fire at the same second.
- Retry policy — on a failed invocation, the scheduler retries up to 185 times over a configurable retention window (up to 24 hours). Configure a DLQ to capture events that exhaust all retries.
- Schedule groups — logical containers for organising schedules. Useful for applying tags and managing permissions at group level.
Delivery guarantee
EventBridge Scheduler provides at-least-once delivery — it may invoke the target more than once for a single schedule occurrence in rare failure scenarios. Design targets to be idempotent. For Lambda, the scheduler passes a unique scheduledEventId you can use as an idempotency key.
Cron & Rate Expressions
EventBridge Scheduler accepts two expression formats:
Rate expressions
The simplest form — fire every N units of time from when the schedule was created:
rate(5 minutes)— every 5 minutesrate(1 hour)— every hour (singular unit must use singular noun)rate(7 days)— every 7 days
Cron expressions
AWS uses a 6-field cron syntax — cron(minutes hours day-of-month month day-of-week year). All times are UTC.
| 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 | * , , , - , / |
Day-of-month and day-of-week cannot both be specified — one must be ?(no specific value).
Common examples
cron(0 12 * * ? *)— every day at 12:00 UTCcron(0 9 ? * MON-FRI *)— weekdays at 09:00 UTCcron(0 0 1 * ? *)— first day of every month at midnight UTCcron(0/15 * * * ? *)— every 15 minutescron(0 18 L * ? *)— last day of every month at 18:00 UTC
Scheduler vs EventBridge Rules
Before EventBridge Scheduler existed, the standard approach was an EventBridge Rule with a Schedule source. Both still work; the rule-based approach is simpler for basic use cases already wired into an event bus.
| EventBridge Scheduler | EventBridge Rules (schedule) | |
|---|---|---|
| Released | November 2022 | Original CloudWatch Events (2015) |
| One-time schedules | Yes | No |
| Flexible time windows | Yes | No |
| Retry policy | Yes (up to 185 retries, 24 h window) | Limited (target-level only) |
| DLQ support | Yes (on the schedule) | Yes (on the rule target) |
| Supported targets | 270+ AWS API operations directly | ~20 AWS services via event bus |
| Scale | Millions of schedules per account | 300 rules per event bus (default) |
| Best for | New workloads, per-user schedules, one-time jobs | Simple recurring tasks already in an event-driven architecture |