# 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`](https://effect.plants.sh/scheduling/repetition-and-retry/)
(re-run on failure), [`Effect.repeat`](https://effect.plants.sh/scheduling/repetition-and-retry/)
(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.

```ts
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.

## Time is a service

Schedules never call `Date.now` or `setTimeout` directly. Every delay is realized
through the [`Clock`](https://effect.plants.sh/scheduling/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.

## In this section

- **[Schedule](https://effect.plants.sh/scheduling/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](https://effect.plants.sh/scheduling/repetition-and-retry/)** — driving effects
  with `Effect.repeat`, `Effect.retry`, and their `orElse` variants, plus the
  inline `{ times, while, until }` options.
- **[Cron](https://effect.plants.sh/scheduling/cron/)** — calendar-based scheduling with cron
  expressions, time zones, and the `Cron` module.
- **[Clock](https://effect.plants.sh/scheduling/clock/)** — reading time and sleeping through the
  `Clock` service, and controlling time in tests with `TestClock`.