cron://¶
Consumer-only cron scheduler. Fires synthetic exchanges according to a
cron expression. Supports five-field and six-field expressions, the
@yearly/@monthly/@weekly/@daily/@hourly shortcuts, and
@every <go-duration>. Helix-native extensions add IANA tz,
repeatCount, includeMetadata, multi-consumer fanout, and
suspend/resume.
Use cron:// for time-of-day work ("9am every weekday"). For
interval-only schedules (every N seconds), timer:// is
simpler.
URI shape¶
<name> is the endpoint identifier. <expr> is required.
Supported expressions¶
| Form | Example | Meaning |
|---|---|---|
@every <go-duration> |
@every 30s |
Fire every 30 seconds. |
@yearly / @annually |
— | 0 0 1 1 * |
@monthly |
— | 0 0 1 * * |
@weekly |
— | 0 0 * * 0 |
@daily / @midnight |
— | 0 0 * * * |
@hourly |
— | 0 * * * * |
| 5-field | 0 9 * * 1-5 |
minute hour dom month dow |
| 6-field | */10 * * * * * |
second minute hour dom month dow |
URL-encoded + characters decode to spaces (so ?schedule=0+9+*+*+1-5
works in YAML where ? query parsing is finicky). Fields support
ranges (1-5), lists (MON,WED), steps (*/15), and combinations
(9-17/2).
Parameters¶
| Param | Type | Default | Description |
|---|---|---|---|
name |
path | — | Endpoint identifier. |
schedule |
string | — | Required. Cron expression (any of the forms above). |
tz |
string | Local |
IANA timezone (UTC, America/New_York, Europe/Berlin). Invalid values warn and fall back to Local. |
repeatCount |
integer | 0 |
Maximum number of fires; 0 = unlimited. |
includeMetadata |
boolean | false |
Set the HelixCron* properties and the HelixCronFiredTime / HelixCronMessageTimestamp In headers (see below). |
synchronous |
boolean | false |
Accepted for cross-framework compat; Helix is synchronous by default. |
Body shape¶
The In body of each fire is the endpoint name (a string). Set your own body in the next step.
Headers¶
Set unconditionally on every fire (back-compat):
| Header | Description |
|---|---|
cron.fireTime |
RFC3339-formatted fire instant. |
cron.name |
Endpoint name. |
cron.schedule |
The configured schedule string. |
Set when includeMetadata=true:
| Exchange property | Description |
|---|---|
HelixCronCounter |
1-based fire counter. |
HelixCronName |
Endpoint name. |
HelixCronSchedule |
Schedule string. |
HelixCronTimezone |
Timezone name (e.g. UTC). |
HelixCronFiredTime |
Fire instant as time.Time. |
| In header | Description |
|---|---|
HelixCronFiredTime |
Fire instant. |
HelixCronMessageTimestamp |
Fire instant as unix-millis. |
Examples¶
Nightly summary email at midnight UTC:
- id: nightly
from: cron://nightly?schedule=@daily&tz=UTC
steps:
- to: direct://build-nightly-summary
- to: smtp://relay.example.com:587?to=ops@example.com&subject=Nightly%20summary
Weekdays at 9am Eastern:
- id: morning-brief
from: cron://brief?schedule=0+9+*+*+1-5&tz=America/New_York
steps:
- to: direct://collect-news
- to: slack://#general?botToken=xoxb-...
Every 15 seconds (interval style):
Six-field, seconds precision — every 10 seconds:
Run once, then exit:
Behavior notes¶
cron://is consumer-only.CreateProducerreturnsErrProducerNotSupported.- Multiple consumers share one scheduler. Identical names register on the same Endpoint; one goroutine wakes up at each fire and dispatches to every non-suspended consumer.
- Field semantics. 5-field is Unix-cron; 6-field puts seconds in
front. Day-of-week is
0..6with0= Sunday. - Timezone affects evaluation. "9am every weekday" with
tz=America/New_Yorkshifts with DST. - No persistent state. A
repeatCount=10schedule that's restarted fires another 10 times — counter does not survive process exit. For durable schedules, use an external scheduler. - Failure mode. If a fire's processor errors, it's logged and the scheduler continues to the next fire. The scheduler keeps a hard upper bound on its match search (~4 years) so a pathological expression won't busy-loop.
Source¶
pkg/component/cron/cron.go— Component, Endpoint, Consumer, scheduler, and the embedded cron expression parser.
See also¶
- Interval-only schedules:
timer://