Schedules
Choose when code runs and understand retries, skipped occurrences, and timing.
A Schedule is a Trigger that runs a Handler at a time or interval. First deploy the code, as shown in Your first Handler.
wings trigger add <handler-id> --schedule "every:1d@09:00" --tz Asia/Tokyo --args '{}'
wings trigger list <handler-id>
Check the time and time zone in the list. This example runs every morning at 09:00 in Japan. Starts may be delayed when the service is busy.
Schedule formats
| Format | When it runs |
|---|---|
every:5m, every:2h |
Every five minutes or two hours |
every:1d@09:00 |
Daily at 09:00 |
weekly:mon,wed,fri@09:00 |
Monday, Wednesday, and Friday at 09:00 |
monthly:1@09:00 |
On the first of each month at 09:00 |
at:2027-01-01T09:00+09:00 |
Once at the specified time |
cron:0 9 * * 1-5 |
Weekdays at 09:00, using five-field cron |
Without --tz, the CLI uses its computer's time zone.
Specify the intended zone explicitly.
The shortest interval is 5 minutes for Free and 1 minute for members.
It is 15 minutes during a new Free account's first 7 days.
Retries and skipped occurrences
Once an occurrence's Handler code has started, Wings never starts it again automatically. Only attempts that failed before starting are retried.
If a retry would run at or after the next occurrence, Wings skips the older occurrence.
Its status is skipped with the reason superseded_by_next_occurrence.
No Run is created for it.
An already scheduled retry checks again when it runs. It skips if a newer occurrence has been created. Otherwise, it runs even if it is late.
When the daily time allowance runs out, a retry waits until midnight UTC only if midnight comes before the next occurrence. A five-minute Schedule usually skips that occurrence. A one-time Schedule has no next occurrence, so it is retried.
Avoid duplicate actions
Once a start is recorded, the occurrence counts as started even if a lost response prevented the code from running. Returning a result or an error does not trigger an automatic retry. The same applies when an external API returns 429 or 5xx.
An unknown external outcome, such as a timeout, ends as dead with external_outcome_unknown.
Check whether the external service completed the action before running it again manually.
Build any required retries into your Handler.
Use event.agiWings.occurrenceId to recognize the same occurrence and prevent duplicate actions.
Timing and limits
Different Schedules can run at the same time.
They are not guaranteed to start in time order.
Exhausted queue delivery attempts end with queue_delivery_exhausted.
Enabled Schedules have a combined hourly limit.
Creating, changing, or enabling a Schedule above that limit returns schedule_rate_limit_exceeded.
You can still reduce the total, disable a Schedule, or delete it.