Ray9

Schedules

Cron expressions in a named timezone, overlap policy, per-run caps, retries, cancellation, and what Ray9 does about an occurrence it missed.

Cron and timezone

A schedule is a cron expression plus a named IANA timezone, attached to a pinned Flow version. The timezone is not optional — "every morning at 7" is meaningless without one, and a schedule that drifts an hour twice a year is a schedule you cannot trust.

Ray9 uses five-field cron expressions and offers minute-level recurrence. Before you enable a schedule, it previews the next occurrences in your chosen timezone, so daylight-saving transitions are something you see rather than something you discover.

Schedules pin a Flow version. A published Flow keeps running exactly the definition it was pinned to until you deliberately promote it. See Flows for how promotion and rollback work.

Overlap policy

Every schedule declares what to do when an occurrence comes due and the previous run has not finished.

ModeBehaviour
skipDrop the new occurrence. Use this when a stale run is worse than a missing one.
queue_oneHold exactly one occurrence and start it when the current run finishes.
allowRun concurrently, up to an explicit concurrency limit.

There is no implicit default that quietly stacks runs on top of each other. A slow target on a five-minute schedule is a well-understood way to burn credits, and Ray9 makes you choose.

Caps and budgets

A schedule carries limits, and they are enforced rather than advisory:

  • Per-run caps on pages, items, elapsed time, and credits.
  • An optional schedule budget across occurrences.
  • Your organization's run, day, and month budgets, which apply on top.

When a cap is reached, the run stops at a clean boundary and keeps whatever it validly collected. It is reported as budget_denied or as a partial result — not as a failure, and not as a silent truncation. See Credits.

Retries

Retries are bounded and classified. Ray9 does not retry indiscriminately, because most failures are not transient and retrying them is just a way of spending credits to be told the same thing again.

  • A transient provider or platform error retries on the same route, with bounded exponential backoff and jitter.
  • A classified block, challenge, or IP-reputation failure may escalate to a different eligible route, if one exists and the reserved budget allows it.
  • A target-issued rate limit (429, a Retry-After header) is treated as a cooldown obligation. Ray9 waits. It does not rotate IPs to get around a limit the target has explicitly stated.
  • A policy denial is never retried on another route. Neither is auth_required — a missing credential is not a routing problem.

Every attempt, including the failed ones, is retained with its route and its evidence. See Execution routes for the failure categories.

Cancellation

You can cancel a run at any point. Ray9 tells you whether the cancellation is immediate or cooperative — a browser part-way through a navigation step is asked to stop, and terminated after a grace period if it does not.

Cancelling a run does not cancel the schedule. Pausing a schedule stops future occurrences without deleting any configuration, and without cancelling a run that is already in flight. Resuming asks for confirmation if the pinned version or the credentials it depends on have gone stale in the meantime.

Missed occurrences

Things go wrong: a deploy, an outage, a schedule enabled while a long run was already going. Ray9's answer is a bounded catch-up policy, chosen deliberately rather than assumed.

When an occurrence is missed, Ray9 does not silently replay an unbounded backlog — waking up to four hundred queued runs and a drained credit balance is not a recovery, it is a second incident. Instead, a schedule's catch-up policy decides whether to run zero missed occurrences, one, or a bounded number of them.

Occurrence identity is what makes this safe. Each occurrence has a stable slot derived from the schedule and its cron expression, so an occurrence is materialized exactly once even if the trigger fires twice. A duplicate fire cannot become a duplicate run, a duplicate charge, or a duplicate record.

Health

An enabled schedule shows its next projected run and the health of its recent ones. That projection is a display, not the trigger — a schedule's occurrences are driven by durable, keyed registration rather than by anything polling a next-due timestamp, which is why they survive restarts.

Runs that stop early for actionable reasons get their own state rather than being flattened into "failed". A run that could not proceed because it needs a credential says so; one that hit a budget cap says so. The point of a schedule is to be able to stop watching it, and that only works if the states it reports are honest.

On this page