Skip to content

EventBridge Scheduler

Protocol: REST JSON Endpoint: http://localhost:4566/

Supported Actions

Action Method Path Description
CreateScheduleGroup POST /schedule-groups/{Name} Create a schedule group
GetScheduleGroup GET /schedule-groups/{Name} Get schedule group details
DeleteScheduleGroup DELETE /schedule-groups/{Name} Delete a schedule group and its schedules
ListScheduleGroups GET /schedule-groups List schedule groups
CreateSchedule POST /schedules/{Name} Create a schedule
GetSchedule GET /schedules/{Name} Get schedule details
UpdateSchedule PUT /schedules/{Name} Update a schedule
DeleteSchedule DELETE /schedules/{Name} Delete a schedule
ListSchedules GET /schedules List schedules
TagResource POST /tags/{ResourceArn} Add tags to a schedule group
UntagResource DELETE /tags/{ResourceArn}?TagKeys=... Remove tags from a schedule group
ListTagsForResource GET /tags/{ResourceArn} List tags on a schedule group

Schedule Invocation

When floci.services.scheduler.invocation-enabled is true (the default), a background dispatcher fires schedule targets on time. Supported expressions:

  • at(YYYY-MM-DDTHH:mm:ss) — one-time fire; honors ScheduleExpressionTimezone (default UTC) and ActionAfterCompletion=DELETE.
  • rate(N unit) — repeating fire (minutes, hours, days, weeks).
  • cron(minute hour day-of-month month day-of-week year) — AWS 6-field cron; honors ScheduleExpressionTimezone. Day-of-week is 1-7 or SUN-SAT, so 2 is Monday and cron(30 2 ? * 2#1 *) is the first Monday of the month.

State=DISABLED schedules and schedules outside their StartDate/EndDate window are skipped. The dispatcher ticks every floci.services.scheduler.tick-interval-seconds (default 10).

Supported target types: SQS, Lambda, SNS, ECS RunTask, EventBridge PutEvents, and unqualified Step Functions state machine ARNs. A Step Functions target starts an asynchronous execution with the schedule target's Input, or {} when Input is absent. Scheduler delivery succeeds when StartExecution is accepted; a later workflow failure does not trigger Scheduler retries.

Retries and dead-letter queues

A failed invocation is retried after a deterministic capped exponential delay until the target's RetryPolicy is exhausted. The delay starts at 60 seconds and is capped at 86400 seconds. Missing fields use the AWS defaults: MaximumEventAgeInSeconds=86400 and MaximumRetryAttempts=185. Retries run when due, without undocumented AWS jitter. Each occurrence retries independently, so a failing occurrence does not delay later rate or cron fires. Pending retries are in memory and are dropped when the process restarts, or when a schedule is disabled, updated, or deleted. Targets Floci cannot deliver to count as failed invocations. Lambda targets are invoked asynchronously, so function errors are not retried by the scheduler.

When an occurrence is exhausted and DeadLetterConfig.Arn names a standard SQS queue, Floci sends the fully materialized target request as a JSON body to that queue with the message attributes ERROR_CODE, ERROR_MESSAGE, EXECUTION_ID, EXHAUSTED_RETRY_CONDITION, IS_PAYLOAD_TRUNCATED, RETRY_ATTEMPTS, SCHEDULED_TIME, SCHEDULE_ARN, and TARGET_ARN. FIFO queues and non-SQS ARNs are logged and skipped. An at schedule with ActionAfterCompletion=DELETE is deleted once its occurrence is delivered or exhausted. For an SQS target, the body contains MessageBody and QueueUrl. Non-JSON target input is encoded as a JSON string field.

Configuration

Variable Default Description
FLOCI_SERVICES_SCHEDULER_ENABLED true Enable or disable the service
FLOCI_SERVICES_SCHEDULER_INVOCATION_ENABLED true Run the background dispatcher that fires scheduled targets (false = CRUD-only)
FLOCI_SERVICES_SCHEDULER_TICK_INTERVAL_SECONDS 10 How often the dispatcher scans for due schedules (seconds)

Not Yet Supported

  • FlexibleTimeWindow jitter (fires deterministically at the scheduled time)
  • NextToken-based pagination for List operations

Examples

export AWS_ENDPOINT_URL=http://localhost:4566

# Create a schedule group
aws scheduler create-schedule-group \
  --name my-group \
  --endpoint-url $AWS_ENDPOINT_URL

# List schedule groups
aws scheduler list-schedule-groups \
  --endpoint-url $AWS_ENDPOINT_URL

# Create a schedule in the default group
aws scheduler create-schedule \
  --name my-schedule \
  --schedule-expression "rate(1 hour)" \
  --flexible-time-window '{"Mode":"OFF"}' \
  --target '{
    "Arn": "arn:aws:lambda:us-east-1:000000000000:function:my-func",
    "RoleArn": "arn:aws:iam::000000000000:role/scheduler-role"
  }' \
  --endpoint-url $AWS_ENDPOINT_URL

# Create a schedule with retry policy and dead-letter queue
aws scheduler create-schedule \
  --name my-resilient-schedule \
  --schedule-expression "rate(5 minutes)" \
  --flexible-time-window '{"Mode":"FLEXIBLE","MaximumWindowInMinutes":10}' \
  --target '{
    "Arn": "arn:aws:sqs:us-east-1:000000000000:my-queue",
    "RoleArn": "arn:aws:iam::000000000000:role/scheduler-role",
    "RetryPolicy": {"MaximumEventAgeInSeconds":3600,"MaximumRetryAttempts":5},
    "DeadLetterConfig": {"Arn":"arn:aws:sqs:us-east-1:000000000000:my-dlq"}
  }' \
  --endpoint-url $AWS_ENDPOINT_URL

# Get a schedule
aws scheduler get-schedule \
  --name my-schedule \
  --endpoint-url $AWS_ENDPOINT_URL

# Update a schedule
aws scheduler update-schedule \
  --name my-schedule \
  --schedule-expression "rate(30 minutes)" \
  --flexible-time-window '{"Mode":"OFF"}' \
  --target '{
    "Arn": "arn:aws:lambda:us-east-1:000000000000:function:my-func",
    "RoleArn": "arn:aws:iam::000000000000:role/scheduler-role"
  }' \
  --state DISABLED \
  --endpoint-url $AWS_ENDPOINT_URL

# Delete a schedule
aws scheduler delete-schedule \
  --name my-schedule \
  --endpoint-url $AWS_ENDPOINT_URL

# Delete a schedule group (cascades to all schedules in the group)
aws scheduler delete-schedule-group \
  --name my-group \
  --endpoint-url $AWS_ENDPOINT_URL

# Add tags to a schedule group (tags apply to schedule groups only)
aws scheduler tag-resource \
  --resource-arn arn:aws:scheduler:us-east-1:000000000000:schedule-group/my-group \
  --tags Key=env,Value=prod Key=owner,Value=Alice \
  --endpoint-url $AWS_ENDPOINT_URL

# List tags on a schedule group
aws scheduler list-tags-for-resource \
  --resource-arn arn:aws:scheduler:us-east-1:000000000000:schedule-group/my-group \
  --endpoint-url $AWS_ENDPOINT_URL

# Remove tags from a schedule group
aws scheduler untag-resource \
  --resource-arn arn:aws:scheduler:us-east-1:000000000000:schedule-group/my-group \
  --tag-keys env owner \
  --endpoint-url $AWS_ENDPOINT_URL

Default Schedule Group

A default schedule group is automatically created on first access. Schedules created without specifying a group are placed in the default group. The default group cannot be deleted.