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.
rflow_version: 1
name: price-keeper
config:
port: 3940
db_connection: ${DATABASE_URL}
signer:
aws_kms:
region: eu-west-1
networks:
- name: ethereum
chain_id: 1
rpc: ${ETH_RPC}
relayers:
keeper:
networks: [ethereum]
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.
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). Shortening
every (say 1h β 30s) and restarting clamps the stale cursor to at most
one new interval out, so the faster cadence takes effect promptly.
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, or keep it fully off-chain. Polling a web feed or API? The
web trigger does the fetch, parse, new-item diff
and dedupe for you. To rehearse steps without waiting for the schedule, use
rflow test with a
{ "scheduled_for": "..." } fixture.