Peter Wielander 746de8b997 [e2e] Add a cycle-hook scenario to the event-log race repro
`wake-loop` creates its hooks once, at the top, before any wait exists, so it
commits one `hook_created` and never another. That leaves a state it can never
reach: a hook write landing while a wait is already open.

Two production runs died there. `githubUserMonitor` on core 5.0.0-beta.48 mints
a fresh hook inside every cycle, races it against a heartbeat sleep, and
disposes it only when the sleep wins — so after any cycle the hook won, the next
cycle's `hook_created` commits with that cycle's abandoned sleep still counting
down. An open wait is exactly what decides whether the runtime settles a hook's
awaiter from the suspension's own writes or re-reads the log first.

`cycle-hook` is that loop. Its 55-cycle production original is reproduced event
for event in the ledger the scenario asserts on: 56 `hook_created`, 54
`hook_disposed`, 55 `wait_created`, 54 `wait_completed`, 18 `hook_received`, and
one wait still open at the end.

The driver walks the cycle index rather than holding one hook, resuming each
cycle's own token, and aims a configurable share of those resumes at the
heartbeat deadline so a `hook_received` commits next to a `wait_completed`. The
rest are left to the sleep, since a hook win is what sets up the next cycle's
open-wait create; `pressure.cycleHook.createsUnderOpenWait` reports how often the
run actually reached that state, so a clean result can be told apart from a run
that never got there.

Validated against world-local: three runs, all completed, each reporting
`createsUnderOpenWait: 3` across a mix of both branches. That says the shape
drives the intended interleaving, not that it reproduces the corruption — the
production failures were on world-vercel, and world-local at three runs
resolves nothing about a rate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 10:57:38 -07:00
2025-10-23 12:07:52 +03:00
2025-10-23 12:07:52 +03:00
2025-10-23 12:07:52 +03:00
2025-10-23 12:07:52 +03:00
2025-10-23 12:07:52 +03:00

Workflow SDK logo

Workflow SDK

Vercel logo npm version License Join the community on GitHub

Workflow SDK makes TypeScript and JavaScript functions durable. It persists workflow progress, retries failed steps, and provides built-in observability. Workflows can suspend without using compute while they wait.

Quick start

Install the SDK in an existing project:

npm install workflow

Configure the integration for your framework. For example, with Next.js:

// next.config.ts
import { withWorkflow } from 'workflow/next';

export default withWorkflow({});

Then start a workflow from an API route, Server Action, or other server-side code:

import { start } from 'workflow/api';
import { onboardUser } from './workflows/onboard-user';

await start(onboardUser, ['hello@example.com']);

Run your app, then open the local observability UI in another terminal:

npm run dev
npx workflow web

Choose your framework in the getting-started guides.

Note

The workflow package includes its full documentation, so coding agents can read version-matched guides locally from node_modules/workflow/docs.

Run anywhere

Local development uses the bundled backend with no configuration. Deploy to Vercel for managed storage, queuing, scaling, and observability. To self-host, use the Postgres backend or implement a custom World.

The Worlds page lists maintainer-curated third-party Worlds, including self-hosted and managed options. Submit your World by updating the Worlds Manifest.

Community

The Workflow SDK community lives on GitHub Discussions, where you can ask questions, share ideas, and show what you have built.

Contributing

Contributions are welcome. Use issues and discussions to collaborate with the team and wider community. By participating, you agree to our Code of Conduct.

Security

If you find a security vulnerability in Workflow SDK, disclose it responsibly instead of opening a public issue.

To participate in our Open Source Software Bug Bounty program, please email responsible.disclosure@vercel.com. We will add you to the program and provide further instructions for submitting your report.

S
Description
workflow: Creates durable, resumable workflows using Vercel's Workflow SDK. Use when building workflows that need to survive restarts, pause for external events, retry…; workflow-init: Install and configure Vercel Workflow SDK before it exists in node_modules. Use when the user asks to "install workflow", "set up workflow", "add durable…
Readme 140 MiB
Languages
TypeScript 88.8%
JavaScript 5.9%
Rust 4%
CSS 0.5%
Python 0.4%
Other 0.3%