Use this file to discover all available pages before exploring further.
Workflow.step is the fundamental building block of durable workflows. Each step’s result is automatically cached in Durable Object storage so that on workflow replay, completed steps are skipped and their cached value is returned directly.
Unique name for this step within the workflow. Used as the cache key in
Durable Object storage, and appears in logs and event traces. Two steps
with the same name in the same workflow will share their cached result.
The effectful computation to run. Can call external APIs, access
databases, or perform any async work. The return value is serialized and
stored — it must be JSON-serializable. Use Effect.asVoid to discard
non-serializable results, or Effect.map to extract serializable fields.
Optional retry configuration. When provided, failed executions are
retried according to the specified policy. Retries are durable — they
persist across workflow restarts.
Total time budget for all retry attempts combined. Once elapsed, the
step fails with RetryExhaustedError regardless of remaining attempts.
Accepts the same formats as delay.
Add ±10% randomness to retry delays to prevent the thundering herd
problem when many clients retry simultaneously. Set to false for
precise, deterministic timing.
Per-attempt timeout. If the step execution does not complete within this
duration, it fails with WorkflowTimeoutError. The timeout applies to
each individual attempt — when combined with retry, each retry
gets the full timeout again. Accepts the same formats as RetryConfig.delay.
Step results are serialized to JSON and stored in Durable Object storage. The value returned by execute must be JSON-serializable (plain objects, arrays, strings, numbers, booleans, null).
// Non-serializable result (ORM object, class instance) — discard ityield* Workflow.step({ name: "Update database", execute: updateRecord(id).pipe(Effect.asVoid),});// Extract serializable fields from a complex resultyield* Workflow.step({ name: "Create order", execute: createOrder(data).pipe( Effect.map((order) => ({ id: order.id, status: order.status })) ),});
const user = yield* Workflow.step({ name: "Fetch user", execute: fetchUser(userId),});// user is typed based on what fetchUser returnsconsole.log(user.email);