Interval trigger
Fire a workflow on a fixed wall-clock cadence β every: 30s | 1m | 5m. No chain
config needed. Unlike cron, intervals allow
sub-minute cadences, so a 30-second keeper needs no cron hacks.
workflows:
price-keeper:
trigger:
interval:
every: 30s # fire every 30 seconds
catch_up: false # optional β skip ticks missed while down (default)
steps:
- id: poke
send_transaction:
network: ethereum
relayer: keeper
to: "0xOracle..."
function: "poke()"| Field | Required | Description |
|---|---|---|
every | β | Fire cadence as a duration (30s, 1m, 5m, 1h). Sub-minute is allowed. Must be positive |
catch_up | false | Replay the ticks missed while rflow was down β see catch-up |
The trigger payload exposes trigger.scheduled_for (the ISO instant) and
trigger.workflow to expressions.
Interval vs cron vs read polling
| Use | Trigger |
|---|---|
| A fixed cadence, "every N seconds/minutes" | interval (every: 30s) |
| A calendar schedule, "09:00 on Mondays", timezones | cron (expression, tz) |
| Fire only when an on-chain value crosses a threshold | read (condition) |
Exactly-once for the cadence
Ticks land on a stable grid anchored at first boot
(anchor, anchor + every, anchor + 2Β·every, β¦; the first fire is one interval
after boot). Each firing claims a trigger key derived from its scheduled
instant β interval:{workflow}:{ISO} β never now(). A restart landing on
the same instant, or a second scheduler, claims the same key and the duplicate
is skipped. Exactly-once, exactly like events and cron.
The next-due instant is persisted per workflow in rflow.interval_state, so the
grid survives restarts: the schedule resumes on the same phase instead of
re-anchoring (which would fire immediately on every boot). If you shorten
every (say 1h β 30s) and restart, the stale long cursor is clamped to at
most one new interval out, so the faster cadence takes effect promptly rather
than waiting out the old hour.
catch-up β missed ticks
Interval catch-up is deliberately distinct from cron's. Cron replays a calendar; an interval replays a fixed-cadence grid off the persisted cursor.
catch_up: false(default): ticks that came due while the process was down are skipped. The cursor jumps forward β staying on the original grid phase β to the first instant after now, and the schedule resumes. No missed tick is claimed.catch_up: true: on boot every grid instant missed while rflow was down is claimed, each under its own scheduled-instant key (so a repeated boot can never double-fire).
Examples
interval: { every: 15s } # every 15 seconds
interval: { every: 1m } # every minute
interval: { every: 5m, catch_up: true } # every 5 minutes, replayed if missedCombine with send_transaction for keeper
pokes and heartbeats, or keep it fully off-chain. Polling a web feed or API
with interval + http_call? The web trigger does
the fetch, parse, new-item diff and dedupe for you. To rehearse an interval
workflow's steps without waiting for the schedule, use
rflow test with a
{ "scheduled_for": "..." } fixture.