Durable workflows

Workflows that resume where they stopped.

Your job died at step 4 of 12. You have no idea what ran and what didn't. Re-running from the top re-charges every API call.

Rotor memoizes each step. If a workflow crashes, it resumes from the last completed step. step.sleep suspends without occupying a worker slot. step.waitForSignal pauses until an external event unblocks it.

import { rotor } from "rotor-sdk"

rotor.workflow("enrich-lead", async ({ step, payload }) => {
  // Memoized — won't re-run if workflow retries
  const company = await step.run("fetch-company", () =>
    apollo.getCompany(payload.domain)
  )

  // Suspends for 24h without occupying a worker
  await step.sleep("wait-for-enrichment", "24h")

  // Resumes exactly here after sleep
  const enriched = await step.run("enrich", () =>
    clay.enrich(company)
  )

  return enriched
})
Read the full docs →

Stop babysitting cron. Start shipping.

Your workflows retry themselves. Your pipeline runs unattended. You sleep.

Start shipping$9 to start. 30-day money back.
Read the docs →