llms.txt
# Workflow SDK documentation
> Workflow SDK is a durable functions framework for JavaScript and TypeScript that makes long-running application logic resilient across stateless compute.
## When to use Workflow SDK
- Category: Developer tools
- Audience: JavaScript developers, TypeScript developers, AI agent builders
Common use cases:
- Build durable workflows and steps
- Run long-lived AI agents with persisted state
- Deploy workflow-backed applications across supported frameworks
## Documentation
---
title: Deploying
description: Deploy workflows locally, on Vercel, or anywhere using pluggable World adapters.
docs_index: /llms.txt
lastUpdated: 2026-10-13
type: overview
summary: Learn how to deploy workflows to different environments using World adapters.
related:
- /worlds/local
- /worlds/postgres
- /worlds/vercel
- /worlds/building-a-world
---
> For an index of all documentation, see [/llms.txt](/llms.txt).
The same workflow code can run locally during development, on Vercel with zero configuration, or on any infrastructure using **Worlds**, which are pluggable adapters that handle storage, queuing, and communication.
## Local development
During local development, workflows use the **Local World** without configuration. The Local World stores workflow data in a `.workflow-data/` directory and processes steps synchronously for development and testing.
```bash
# Run your dev server to use workflows locally
npm run dev
```
You can inspect local workflow data using the CLI:
```bash
npx workflow inspect runs
```
> Learn more about the [Local World](/worlds/local) configuration and internals.
## Deploying to Vercel
Deploy workflows to production on Vercel without configuration. Workflows deployed to Vercel use the **Vercel World**.
The Vercel World provides:
- **Durable storage**: Workflow state persists across function invocations
- **Managed queuing**: The queue processes steps reliably with automatic retries
- **Automatic scaling**: Workflows scale with your application
- **Built-in observability**: View workflow runs in the Vercel dashboard
- **Multi-region**: The region that creates each run also hosts its workflow data, queue, and streams, keeping them close to your users
Deploy your application:
```bash
vercel deploy
```
> **Enable access to System Environment Variables before deploying.** Workflow
> recognizes a Vercel deployment by `VERCEL_DEPLOYMENT_ID`, which Vercel exposes
> to your build and your functions only when the **Enable access to System
> Environment Variables** checkbox is selected under **Settings**, then
> **Environment Variables**, in your project. With it cleared, the deployment
> falls back to the Local World and every run fails on the read-only
> filesystem. See
> [System environment variables](/worlds/vercel#system-environment-variables).
> Learn more about the [Vercel World](/worlds/vercel) and its capabilities, including [multi-region](/worlds/vercel#multi-region).
## Self-hosting & other providers
For self-hosting or deploying to other cloud providers, you can use community-maintained Worlds or build your own.
#### [Explore Worlds](/worlds)
Browse official and community World implementations with compatibility status and performance benchmarks.
#### [Build Your Own](/worlds/building-a-world)
Learn how to implement a custom World for your infrastructure.
### Using a third-party World
To use a different World implementation, set the `WORKFLOW_TARGET_WORLD` environment variable:
```bash
export WORKFLOW_TARGET_WORLD=@workflow/world-postgres
# Plus any world-specific configuration
export DATABASE_URL=postgres://...
```
Each World may have its own configuration requirements. Refer to that World's documentation for details.
## Observability
The [Observability tools](/docs/observability) work with any World backend. By default, they connect to your local environment, but you can configure them to inspect remote deployments:
```bash
# Inspect local workflows
npx workflow inspect runs
# Inspect remote workflows
npx workflow inspect runs --backend @workflow/world-postgres
```
Learn more about [Observability](/docs/observability) tools.
---
For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)
For an index of all available documentation, see [/llms.txt](/llms.txt)
For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)
---
title: Performance
description: "How we measure the Workflow SDK runtime's performance, the metrics we track, and the latest results."
docs_index: /llms.txt
lastUpdated: 2026-10-13
type: reference
summary: The benchmarks we run on the Workflow SDK runtime, how each one is measured, and the latest results.
related:
- /docs/whats-new
- /docs/how-it-works/event-sourcing
- /docs/foundations/hooks
- /docs/foundations/streaming
---
> For an index of all documentation, see [/llms.txt](/llms.txt).
We benchmark the Workflow SDK runtime on Vercel at each point where a workflow waits on it: starting a run, moving from one step to the next, fanning out, resuming from a hook, and delivering a stream. This page explains what each benchmark measures and how, and then shows the [latest results](#latest-results), which compare a new release with an earlier one.
## What we measure
Each benchmark starts a clock at one line of code and stops it at another. The work inside a step is not counted, so the numbers measure the runtime itself. Choose a metric below, then play or scrub through a run to see when its clock runs.
### Time to first step (TTFS)
How long it takes from your app calling [`start()`](/docs/api-reference/workflow-api/start) until the first line of the workflow's first step runs. This covers creating and queuing the run, running the workflow code up to its first step, and starting that step. It is measured on a five-step workflow. See [Steps and long runs](#steps-and-long-runs) for the latest results.
### Step-to-step overhead (STSO)
How long it takes from one step finishing until the next step starts: recording the step's result, resuming the workflow, and starting the next step. It is measured on the same five-step workflow, and at steps 1 to 20, 101 to 120, and 1,001 to 1,020 of a 1,020-step workflow, which shows whether the overhead grows as the run's [event log](/docs/how-it-works/event-sourcing) grows. See [Steps and long runs](#steps-and-long-runs) for the latest results.
### Fan-out (TTFS, TTLS, join)
A workflow starts 64 one-step branches at once with `Promise.all`. The runtime queues the branches in batches, so they start close together and in no fixed order. The first branch (TTFS) and the slowest branch to start, or time to last step (TTLS), are timed from `start()` until that branch's first line runs. The join is timed from the slowest branch finishing until the code after `Promise.all` runs. See [Fan-out](#fan-out) for the latest results.
### Time to resume (TTR)
A workflow creates a [hook](/docs/foundations/hooks) and waits on it for 1 s, the way an agent waits for a person's approval, and then your app calls `resumeHook()`. Time to resume runs from that call until the first line of the workflow's next step runs. Each run resumes five times. See [Resuming a workflow](#resuming-a-workflow) for the latest results.
### Chunk trip time (CTT)
One step replays a recorded AI agent's token stream, 2,593 chunks over 52.4 s, in real time to a [namespaced stream](/docs/foundations/streaming#namespaced-streams) with [`getWritable()`](/docs/api-reference/workflow/get-writable), and a second step in the same run reads it with `getRun(runId).getReadable()`. Chunk trip time runs from the writer writing a chunk until the reader receives it. The same benchmark records how long the whole response takes to reach the reader and how many runs had a chunk delayed by over 1 s. See [Streams](#streams) for the latest results.
## Methodology
- **Platform**: Each version runs the same benchmark app on Vercel production in `iad1`, against the managed [Vercel World](/worlds/vercel), on its own deployment. The versions are measured at the same time. Before measuring, each deployment runs two short workflows and one fan-out that are not counted.
- **Workload**: Every step takes 1 KB of JSON in and out and does 100 ms of simulated work, which the overhead measurements exclude.
- **Runs**: Each version runs every benchmark several times, and each result pools the samples from all of its runs. The run counts are listed with the latest results.
- **Percentiles**: Each percentile pools every sample across a version's runs and uses the nearest-rank method. Half of the samples are at or below the p50 (the median), three quarters at or below the p75, and all but the slowest 1% at or below the p99. With 100 or fewer samples, a p99 is the slowest sample.
### Limits
- The benchmarks run in one region, against one World. Other regions, Worlds, and workloads will see different numbers.
- The versions share the platform while they are measured. Any exception is noted with the results.
- The explainer and the animations are schematic: they show where each clock starts and stops, not real timings.
## Latest results
> **Latest results:** Workflow SDK v5.2.0 compared with v4.8.12, measured October 8, 2026. We run these benchmarks regularly and publish updated results here.
At p75, v5.2.0 is as fast as or faster than v4.8.12 on every benchmark. The largest change is in long runs: 1,000 steps into a run, v5.2.0 adds 70 ms between steps where v4.8.12 adds 1,748 ms.
Both versions ran at the same time and shared the platform. The exception is the 1,020-step benchmark on v4: one of its five runs ran alongside v5.2.0's, and the other four ran on their own afterwards, the same day with the same configuration. Each version ran the sequential workflow 10 times, the agent stream 10 times, the fan-out 25 times, the resume benchmark 25 times, and the 1,020-step run 5 times.

### Steps and long runs
At p75, a five-step workflow reaches its first step in 172 ms on v5.2.0 and 418 ms on v4.8.12, and v5.2.0 adds 109 ms between steps where v4.8.12 adds 618 ms.
Through a 1,020-step run, step-to-step overhead on v4.8.12 grows from 622 ms in steps 1 to 20 to 1,748 ms in steps 1,001 to 1,020, at p75. On v5.2.0 it is 110 ms and 70 ms. The median run takes 21.0 min on v4.8.12 and 3.0 min on v5.2.0.

### Fan-out
At p75, v5.2.0 starts the first of 64 branches in 360 ms against 478 ms on v4.8.12, then starts the slowest branch at about the same time (996 ms against 972 ms) and joins in 448 ms against 464 ms.

### Resuming a workflow
At p75, a workflow waiting on a hook resumes in 425 ms on v5.2.0 against 699 ms on v4.8.12.

### Streams
The agent produced its 2,593-chunk response over 52.4 s. On v4.8.12 the writer step manages about 12 chunks per second, so the response takes 226.1 s to reach the reader. v5.2.0 writes streams over a WebSocket by default, keeps up at about 49 chunks per second, and delivers the response in 53.5 s.
At p75, a chunk reaches the reader in 102 ms on v5.2.0 against 172 ms on v4.8.12. v5.2.0 had a chunk delayed by over 1 s in 0 of 10 runs, against 6 of 10 on v4.8.12.
On the Vercel World, [`WORKFLOW_STREAMS_TRANSPORT`](/docs/configuration/worlds#workflow_streams_transport) sets the transport for stream writes.

### All results
Every measured value from the latest results. Percentiles follow the [methodology](#methodology) above.
| Metric | v4.8.12 | v5.2.0 | Change | Samples per version |
| ----------------------------------------------- | -------: | ------: | -----------: | ------------------: |
| **Sequential workflow, 5 steps, 10 runs** | | | | |
| Time to first step, p75 | 418 ms | 172 ms | 2.4× faster | 10 runs |
| Time to first step, slowest run | 451 ms | 253 ms | 1.8× faster | 10 runs |
| Step-to-step overhead, p75 | 618 ms | 109 ms | 5.7× faster | 40 gaps |
| Step-to-step overhead, p99 | 777 ms | 327 ms | 2.4× faster | 40 gaps |
| **Long run, 1,020 steps, 5 runs** | | | | |
| Step overhead, steps 1 to 20, p75 | 622 ms | 110 ms | 5.7× faster | 95 gaps |
| Step overhead, steps 101 to 120, p75 | 719 ms | 74 ms | 9.7× faster | 95 gaps |
| Step overhead, steps 1,001 to 1,020, p75 | 1,748 ms | 70 ms | 25.0× faster | 95 gaps |
| Whole run, median wall time | 21.0 min | 3.0 min | 7.0× faster | 5 runs |
| **Fan-out, 64 parallel branches, 25 runs** | | | | |
| First branch starts, p75 | 478 ms | 360 ms | 1.3× faster | 25 runs |
| Slowest branch to start, p75 | 972 ms | 996 ms | No change | 25 runs |
| Join, p75 | 464 ms | 448 ms | No change | 25 runs |
| **Resume after 1 s idle, 25 runs of 5 resumes** | | | | |
| Time to resume, p50 | 619 ms | 383 ms | 1.6× faster | 125 resumes |
| Time to resume, p75 | 699 ms | 425 ms | 1.6× faster | 125 resumes |
| **Agent stream, 52.4 s recording, 10 runs** | | | | |
| Delivery, median wall time | 226.1 s | 53.5 s | 4.2× faster | 10 runs |
| Chunk trip time, p75 | 172 ms | 102 ms | 1.7× faster | 25,930 chunks |
---
For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)
For an index of all available documentation, see [/llms.txt](/llms.txt)
For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)
---
title: "What's new in v5?"
description: Workflow SDK 5.0 highlights, breaking changes, and how to upgrade from 4.x.
docs_index: /llms.txt
lastUpdated: 2026-10-15
type: guide
summary: See what changed in Workflow SDK 5.0 and how to move an app from 4.x.
related:
- /docs/getting-started
- /docs/configuration
- /docs/foundations/cancellation
---
> For an index of all documentation, see [/llms.txt](/llms.txt).
We recommend upgrading to v5 to get all of the performance, cost, and feature improvements listed below. Install the migration skill, then tell your agent to migrate your app from Workflow SDK v4 to v5.
```bash
npm install workflow@latest
npx skills add https://github.com/vercel/workflow --skill migrating-workflow-v4-to-v5
```
**Prompt for coding agents**
Upgrade this app from Workflow SDK v4 to v5 using the migrating-workflow-v4-to-v5 skill. Bump \`workflow\` and every \`@workflow/\*\` dependency to ^5.0.0, apply the skill's mechanical rewrites, and report the behavior changes it flags instead of silently changing them. Then verify: reinstall, rebuild, typecheck, run the test suite, and execute one workflow end to end.
> Workflow SDK v4 remains installable as `workflow@4` and receives stability
> fixes. Its documentation lives at [/v4/docs](/v4/docs).
## Highlights
### Faster and cheaper runs

At p75, v5.2.0 is as fast as or faster than v4.8.12 on every benchmark.
The largest change in v5 has no API surface: the runtime does far less work per unit of progress. The time between calling `start()` and your first step body executing is now less than half of what it was in v4. This is made possible by many smaller optimizations:
**A workflow invocation now does as much as it can in a single pass.** In 4.x, progress was largely deferred to the queue: an invocation would execute a step, hand back to the queue, and let a fresh invocation pick up the next one. v5 creates and executes several steps inline per suspension, in parallel, and only uses the queue for a wait, a hook, or when the function approaches its timeout.
**The runtime avoids waiting on the persistence layer where it can determine that it is safe for your workload.** The runtime skips many API calls when they aren't needed, such as requesting the event log on a run's first invocation. Step creation is folded into step execution rather than being its own round trip. The inline loop consumes the event-log delta from the previous step's write instead of re-listing events. Each optimization is gated on specific runtime conditions and can be turned off individually. See [Runtime tuning](/docs/configuration/runtime-tuning).
**The workflow VM is kept alive across inline steps.** Within one invocation, a step- or attribute-driven suspension keeps the live VM and hydrated state, including when hooks or waits are open or created at the same boundary, so the next iteration appends only the newly written events instead of rebuilding the sandbox and replaying the whole log. Step inputs made of plain data or standard built-ins keep this fast path; see [`WORKFLOW_RETAINED_VM`](/docs/configuration/runtime-tuning#workflow_retained_vm).
**Replay no longer downloads recorded step inputs.** Replay recomputes step arguments by re-running workflow code, so it reads the event log without the `input` of each step. For workflows that pass growing state into their steps, this removes the part of the replay transfer that grew quadratically with the run. Worlds opt in through [`resolveData: 'skip-step-inputs'`](/docs/api-reference/workflow-runtime/world/storage#eventslist), and Vercel Workflows supports it.
**Resuming a hook takes one round trip instead of two.** `resumeHook()` writes the `hook_received` event and dispatches the queue message concurrently, with a `(runId, resumeId)` dedup constraint keeping the two writers converging on exactly one event. See [Resilient hook resumption](/docs/changelog/resilient-resume).
**A suspension's writes go out as one batch.** The `step_created` and `wait_created` events a suspension produces are folded into a single durable write with a per-event outcome, instead of one request each, and a fan-out's inline step bodies start straight off that commit rather than each claiming its step first. This engages on Worlds that implement the batch API and can be turned off with [`WORKFLOW_BATCH_TRANSITIONS=0`](/docs/configuration/world