Skip to content
cloudhost
Workflows

Work in many steps, carried to the end.

A run goes step by step and keeps each step's result. If a server fails or you deploy a new version, the run carries on from the last finished step, and a finished step never runs again.

What you get

  • In your own function

    A function exports workflow(event, step, env, ctx) and writes each step with step.do. No server, queue or table to hold the run's state.

  • Retries for each step

    A step that throws is retried on its own, with backoff and a timeout. Mark an error that is not worth retrying with NonRetryableError.

  • Sleeps of up to months

    step.sleep and step.sleepUntil hold a run until the time you set, from seconds to months. Nothing runs meanwhile, and it costs nothing.

  • Wait for an event

    step.waitForEvent holds a run until an event of a given type arrives, with the timeout you set. An event that arrives early is kept for the step that waits for it.

  • Talk to a running run

    Send a run in progress a signal, query its state or update its data. Cancel it by hand or when an event arrives.

  • Parallel steps and child runs

    Run several steps at once and wait for all of them, choose the next path from a step's result, or start another workflow from a run.

  • Undo finished work

    If a step fails midway, compensating steps undo the earlier steps' work, such as refunding a charge. A run parked on a failure resumes from there once the cause is fixed.

  • Flow control

    Concurrency per key, throttling and rate limits, debounce and batching of bursts, priority, and one run at a time per key, such as one customer.

  • Start from anywhere

    Start a run from the API, the CLI, MCP or the dashboard, or let an event, a cron schedule, an HTTP request or a queue message start it.

  • Idempotent starts

    Starting again with the same unique id returns that run and starts nothing new. Each step gets its own idempotency key too, so its outside work is not done twice.

  • Each run keeps its version

    A run that has started finishes on the version of the code it started with, even if you deploy a new one while it runs.

  • A history of every run

    A list of runs with each one's state, and for each run the history of its steps with their input, output, attempts and errors. Rerun a run from the step you choose.

Many steps, one function

Each step has a name and its result is kept. The run sleeps for an hour, waits up to a week for an approval, then carries on.

export default {
  async workflow(event, step, env) {
    const { order } = event.payload

    const charge = await step.do("charge", ({ idempotencyKey }) =>
      chargeCard(order, idempotencyKey))

    await step.sleep("cool-off", "1h")

    const approved = await step.waitForEvent("approval", { type: "approved", timeout: "7d" })
    if (!approved) throw new step.NonRetryableError("not approved in time")

    await step.do("ship", () => ship(order))
    return { charge: charge.id }
  },
}

Per step

Each step that runs is counted. The time a run spends sleeping or waiting for an event costs nothing. Use comes from the month's credit first, then from the wallet.

Questions

Write your first workflow

One function, a few steps, one command to start.

Sign-up is by invite for now. If you have a code, create your account.

Sign up withEmail codeSMS code