Skip to content

Scheduling

A Schedule is a reusable description of when something should happen again. It answers a single question, repeatedly: given how many times we have recurred so far, how much time has elapsed, and what the last value was — should we go again, and if so, after what delay?

Schedules are pure values, so you build them once and reuse them everywhere. The same Schedule can drive Effect.retry (re-run on failure), Effect.repeat (re-run on success), a polling loop, or a cron-style job. Because the recurrence policy is decoupled from the work, you can compose backoff, jitter, attempt caps, and stop conditions independently of the effect they govern.

import { Effect, Schedule } from "effect"
// A capped exponential backoff: start at 200ms, double each time, but never
// wait more than 5 seconds, and give up after 5 retries.
const policy = Schedule.exponential("200 millis").pipe(
Schedule.either(Schedule.spaced("5 seconds")), // cap the delay
Schedule.jittered, // spread retries to avoid thundering herds
Schedule.both(Schedule.recurs(5)) // hard attempt cap
)
const fetchData = Effect.fail("boom" as const)
// Reuse the same policy with retry. fetchData knows nothing about the policy.
const withRetry = fetchData.pipe(Effect.retry(policy))

The delays and stop conditions live in policy; fetchData knows nothing about them. Swapping the policy never touches the effect.

Schedules never call Date.now or setTimeout directly. Every delay is realized through the Clock service in the Effect runtime. That indirection is what makes scheduled code testable: under TestClock you can advance hours of simulated time in microseconds, so a test for an exponential-backoff retry runs instantly and deterministically.

  • Schedule — the built-in constructors (recurs, spaced, exponential, fibonacci, fixed, windowed, cron) and the combinators (both, either, andThen, jittered, while, addDelay, tapOutput, …) used to compose them.
  • Repetition & Retry — driving effects with Effect.repeat, Effect.retry, and their orElse variants, plus the inline { times, while, until } options.
  • Cron — calendar-based scheduling with cron expressions, time zones, and the Cron module.
  • Clock — reading time and sleeping through the Clock service, and controlling time in tests with TestClock.