aws ecs eventbridge claude-curated

ECS scheduled tasks run a one-shot ECS task on a cron or rate schedule. Useful for batch jobs, periodic housekeeping, scheduled exports, or anything that needs more resources or longer runtime than Lambda comfortably gives you.

Two ways to schedule

EventBridge Rules + RunTask target

The original mechanism. An EventBridge rule with a schedule expression triggers ecs:RunTask against a cluster. The rule needs an IAM role that EventBridge assumes to call RunTask, and that role needs iam:PassRole for the task’s execution and task roles (see ECS Task Roles vs Execution Roles).

EventBridge rule (cron) → RunTask target → ECS task starts

This works fine but EventBridge Rules are coupled to the default event bus and have account-level quotas. They also do not have first-class retry, dead-letter, or flexible time windows.

EventBridge Scheduler

A newer service (launched late 2022). EventBridge Scheduler is purpose-built for scheduled invocations and is the recommended choice for new use cases. It supports:

  • Cron and rate expressions, plus one-time schedules
  • Time zones (rules are UTC-only)
  • Flexible time windows (spread invocations to avoid thundering herd)
  • Built-in retries with exponential backoff
  • Dead-letter queues
  • Per-schedule IAM (no shared event-bus rule role)
  • Higher quotas than EventBridge Rules

For new scheduled tasks: prefer EventBridge Scheduler. Existing EventBridge Rules schedules continue to work.

Cron and rate expressions

Cron (six fields — AWS adds Year):

cron(Minutes Hours Day-of-month Month Day-of-week Year)

Examples:

  • cron(0 8 * * ? *) — every day at 08:00 UTC
  • cron(0/15 * * * ? *) — every 15 minutes
  • cron(0 12 ? * MON-FRI *) — weekdays at noon UTC

You must specify either day-of-month or day-of-week as ? (one or the other, not both). EventBridge Scheduler additionally accepts a time-zone parameter; EventBridge Rules are UTC-only.

Rate:

rate(value unit)

Examples: rate(5 minutes), rate(1 hour), rate(1 day).

Scheduled tasks vs Lambda

When to pick ECS over a scheduled Lambda:

ConcernECS scheduled taskLambda
Max runtimeHours / days15 minutes
MemoryUp to 120+ GB on Fargate10 GB
CPUMultiple vCPU6 vCPU max
Container paritySame image as the main serviceSeparate runtime
Cold startSeconds (image pull)Milliseconds
Cost for short jobsHigherLower
Cost for long jobsLowerHits 15 min limit

ECS wins when:

  • The job runs longer than 15 minutes.
  • It needs heavy CPU/RAM.
  • It shares the application image (and dependencies, config, code).
  • It needs a real OS / native binaries that Lambda’s runtime restricts.

Lambda wins when:

  • The job is short and event-driven.
  • You want zero infra per job.
  • Cold start is acceptable.

Capacity providers

Scheduled tasks can run on:

  • Fargate — pay per task per second.
  • Fargate Spot — up to ~70% discount, with the catch that AWS can reclaim with 2-minute notice. Ideal for idempotent, restartable scheduled jobs (nightly reports, batch backfills).
  • EC2 — if you already run EC2 capacity for services and want to soak up spare cycles.

The capacity provider strategy is set on the task or on the cluster default. For a nightly batch that can tolerate a restart, FARGATE_SPOT weight 1 with FARGATE weight 0 (or low) is typical.

Idempotency

EventBridge guarantees at-least-once delivery. Duplicate firings are rare but possible. Scheduled tasks should be idempotent:

  • Use a deterministic key (e.g. the scheduled time bucket) when writing results.
  • Use conditional writes (If-None-Match on S3, attribute_not_exists on DynamoDB).
  • Use a leader-election lock (DynamoDB conditional update) at the start of the task and exit if another instance already holds the lock for that bucket.

A task that doubles its output silently because of a duplicate fire is a bug — design for the duplicate case from the start.

Operational concerns

  • RunTask is async. A scheduled fire that fails to start a task (e.g. capacity, ENI exhaustion, IAM error) does not auto-retry under EventBridge Rules. EventBridge Scheduler does retry. Either way, monitor FailedInvocations.
  • Logs. Each task run is a separate ECS task with its own log stream. CloudWatch Logs Insights or a log aggregator is necessary to follow runs over time.
  • Concurrency. Two cron expressions firing close together can launch overlapping tasks. If the work cannot run concurrently, build the lock or use a single schedule.
  • Cost monitoring. A scheduled task that misbehaves and runs for hours instead of minutes is invisible without per-task cost tracking. Set task timeout and CloudWatch alarms on RunningTaskCount.

Migration path

If you have existing EventBridge Rules schedules, migration to EventBridge Scheduler is mechanical:

  1. Create a new Scheduler schedule with the same cron expression.
  2. Re-implement the target (RunTask) with a per-schedule role.
  3. Disable the old Rule.

Both can coexist during cutover.

See also

References