Vercel

@workflow/world-vercel

Fully-managed world for Vercel deployments. Zero config, infinitely scalable, built-in authentication.

npmSourceE2E Encrypted

The Vercel World is a fully managed workflow backend for applications deployed on Vercel. It provides scalable storage, distributed queuing, and automatic authentication without configuration.

When you deploy to Vercel, workflows automatically use the Vercel World without requiring setup.

Usage

Deploy your application to Vercel:

vercel deploy

Vercel automatically:

  • Selects the Vercel World backend
  • Configures authentication using OIDC tokens
  • Provisions storage and queuing infrastructure
  • Isolates data per environment (production, preview, development)
Enable Fluid compute before deploying. Workflow is designed to take advantage of Fluid compute for efficient suspension and resumption. Without Fluid compute enabled, each workflow resume incurs a separate function cold start, which can result in significantly higher costs.

Vercel platform documentation

For complete details on pricing, usage limits, and included allotments on Vercel, see the official Vercel documentation:

  • Vercel Workflow: Pricing details, concepts, and observability for Workflow on Vercel
  • Vercel limits: Platform-wide limits, including Workflow-specific constraints
  • Vercel Hobby plan: Free-tier included usage for Workflow and other resources

For self-hosted deployments, use the Postgres World. For local development, use the Local World.

Multi-region

The Vercel World runs in every Vercel Function region. Each workflow run is pinned to a single region at creation time. Its stored state, queue dispatch, and streams are all served from that region without cross-region round trips on the hot path. When your application is deployed in the run's region, as described below, step execution is also region-local.

Multi-region requires workflow version 5.0.0 or later. The 4.x release line does not support region pinning. Runs created by 4.x always live in iad1.

Automatic region pinning

No configuration is needed. A run is pinned to the region of the function that creates it:

  • Deploy your app to a single region (via regions in vercel.json or the project settings), and every run lives there.
  • Deploy to multiple regions for a globally distributed audience, and each run is pinned to the region that served the user who triggered it. Workflow data and streaming stay close to that user.

Explicit region selection

To pin a specific run somewhere else, pass the region option to start():

import { start } from "workflow/api";
import { myWorkflow } from "@/workflows/my-workflow";

const run = await start(myWorkflow, [input], { region: "sfo1" });

The region option controls where the run's data is stored and where its queue messages are dispatched from. It does not deploy your code there. Your workflow and step functions execute in the regions your application is deployed to. For execution to actually happen in the specified region, your app must be deployed there through regions in vercel.json or the Function Regions setting in your project settings. If it isn't, the run's data lives in the requested region but its steps execute in the nearest region your app is deployed to.

Good to know

  • Reads, hook resumes, and stream consumers can come from anywhere. The platform routes them to the run's region automatically.
  • Runs created by 4.x SDKs, including runs that existed before you upgraded, live in iad1 and are unaffected by an upgrade. There is no migration.
  • Hook tokens are currently stored in iad1 for every run, regardless of the run's region. The token-to-run mapping that powers getHookByToken() and resumeHook() lives there so tokens without region information can always be resolved. Hook payloads are not affected. A received payload is recorded on the run's event log, which lives in the run's region like all other run data. This token placement may become a project-level setting in the future.

Limitations

  • No run migration: A run's region is fixed at creation. Existing runs cannot be moved to a different region.
  • Hook minimum retention: experimental_minRetention cannot exceed 30 days.

Observability

Workflow observability is built into the Vercel dashboard on your project page. It respects your existing authentication and project permission settings.

The Vercel World implements the optional world.analytics interface, backed by the same observability data pipeline as the dashboard. Two behaviors are specific to this implementation. Listings scan faster when bounded with a startTime/endTime window, and your plan's observability lookback caps the queryable window. Requesting an older window fails with observability-upgrade-required, and responses include pageInfo with the current and maximum lookback so tools can size date ranges.

The workflow CLI commands open a browser window deeplinked to the Vercel dashboard:

# List workflow runs (opens Vercel dashboard)
npx workflow inspect runs --backend vercel

# Launch the web UI (opens Vercel dashboard)
npx workflow web --backend vercel

The CLI automatically retrieves authentication from the Vercel CLI (vercel login) and infers project/team IDs from your local Vercel project linking.

To use the local observability UI instead of the Vercel dashboard:

npx workflow web --backend vercel --localUi

To override the automatic configuration:

npx workflow inspect runs \
  --backend vercel \
  --env production \
  --project my-project \
  --team my-team \
  --authToken <your-token>

Learn more in the Observability documentation.

Testing & compatibility

E2E Tests

Partial100% passing

E2E test pass rate across all tests run for this world. View CI run →

3570
Passed
8
Failed
0
Skipped
3578
Total
View comprehensive E2E test results against all frameworks/configurations
3570
Passed
8
Failed
742
Skipped
4320
Total

Last updated: 8/25/2026, 10:20:33 PM · Commit: 556f3f0

Configuration

In a Vercel deployment, you do not configure the Vercel World yourself. The platform injects everything the runtime needs, including VERCEL_DEPLOYMENT_ID, VERCEL_PROJECT_ID, per-request OIDC tokens, and VERCEL_DEPLOYMENT_KEY for encryption.

Do not set those platform-provided values yourself.

Most users never need to set the WORKFLOW_VERCEL_* variables below. They are only overrides for tools running outside Vercel, such as your laptop or CI, when those tools need to inspect or test a remote Vercel Workflow project and cannot infer the project, team, token, or target environment automatically.

For example, you might set them when running workflow inspect runs --backend vercel from CI without an interactive vercel login, or when running tests against a specific preview deployment. In normal local development, the CLI infers these values from your .vercel directory and Vercel CLI login. In a deployed Vercel function, these variables have no effect on runtime configuration, and the runtime warns if they are set there.

WORKFLOW_VERCEL_ENV

The Vercel environment to target. Options: production, preview. Default: production.

WORKFLOW_VERCEL_AUTH_TOKEN

Vercel API authentication token. Keep this secret in your environment, not in code. Falls back to VERCEL_TOKEN, then to your Vercel CLI login.

WORKFLOW_VERCEL_PROJECT

Vercel project ID (prj_...).

WORKFLOW_VERCEL_PROJECT_NAME

Vercel project name/slug, used for dashboard links.

WORKFLOW_VERCEL_TEAM

Vercel team ID.

WORKFLOW_VERCEL_BACKEND_URL

Custom base URL for the Vercel workflow API proxy. Default: https://api.vercel.com/v1/workflow.

VERCEL_WORKFLOW_SERVER_URL

Custom workflow-server URL for direct runtime requests, or for the proxy to forward to via WORKFLOW_VERCEL_BACKEND_URL. Default: unset; normal deployments should not need this.

WORKFLOW_SEQUENTIAL_REPLAYS

Set WORKFLOW_SEQUENTIAL_REPLAYS=1 to guarantee that at most one orchestrator (flow) invocation runs at a time per workflow run. This behavior is off by default; without it, the runtime relies on idempotency and the event log to tolerate concurrent flow invocations of the same run.

When enabled, each run's orchestrator messages are given their own queue topic and the flow trigger is configured with maxConcurrency: 1, so Vercel Queues processes replays for a given run strictly one at a time. Step executions (which ride the flow topic in the combined handler model) get a per-step topic, so steps keep full parallelism.

This variable is read at both build time and runtime, so it must be set as a project-level environment variable that applies to your build and your deployed functions. Setting it for only one will produce an inconsistent configuration. The same applies to framework integrations that write their own queue trigger configuration instead of using getWorkflowQueueTrigger() from @workflow/builders: they only get the runtime half (per-run topics) unless they also emit maxConcurrency: 1 on their flow trigger.

Because it routes each run's flow invocations through a dedicated maxConcurrency: 1 queue topic, enabling this might lead to higher queue performance overhead.

VERCEL_QUEUE_MAX_DELAY_SECONDS

Maximum delay, in seconds, that Workflow uses for one Vercel Queues continuation message when implementing sleep(). If a workflow sleeps longer than this, the runtime schedules another continuation message when the first one fires, repeating until the sleep's target time is reached. Default: 82800 (23 hours).

Vercel Queues can delay messages for up to 7 days, capped by the message TTL. Because the default TTL is 24 hours, Workflow uses a 23-hour continuation hop to stay safely inside that default.

WORKFLOW_REQUEST_TIMEOUT_MS

Per-request timeout, in milliseconds, for Vercel World HTTP calls to workflow-server. Default: 60000. Clamped to 10000-120000; a value outside that range is pulled into it and warns once.

Below the floor the deadline starts canceling requests that would have succeeded, since a cold route or a large event page can take seconds, and a canceled request is redriven through the queue rather than making progress. The ceiling matches the longest a backend route holds a response. Requests that legitimately outlast it (stream reads and writes, event batches) opt out of the deadline entirely rather than relying on this value.

WORKFLOW_MAX_CHUNKS_PER_REQUEST

Maximum stream chunks written in one Vercel World request. Larger batches are split across multiple requests. Default: 1000. Minimum: 1.

WORKFLOW_EVENTS_TRANSPORT

Workflow run events ship to the Vercel World over a WebSocket instead of one HTTP request each. Default: ws.

Set WORKFLOW_EVENTS_TRANSPORT=http to opt out. Only that exact value disables the WebSocket — any other value, including unset or empty, takes it — so a typo fails toward the default rather than silently pinning a deployment to HTTP.

The setting is ignored when the World is configured with projectConfig and therefore routes through the api-workflow proxy: that endpoint is an HTTP-only REST gateway and does not forward a WebSocket upgrade, so events stay on HTTP and a warning is logged once per process.

Tracing is unaffected by the choice. Each event write emits an http POST client span against the same url.full, regardless of which transport carries it. On the WebSocket path, the span is synthesized around the frame because no HTTP request is made. Attributes distinguish the transports:

AttributeHTTPWebSocket
workflow.events.transporthttpws
workflow.event.typethe event type, e.g. step_startedsame
network.protocol.namewebsocket
workflow.events.ws.urlthe socket the frame went over
workflow.events.ws.req_idper-connection request id, matching the server's log line

The WebSocket handshake is itself a span, workflow.events.ws.connect, so the cost of opening (or eagerly reopening) a connection is attributable rather than showing up as unexplained time inside the first write.

Programmatic configuration

createWorld() accepts explicit API configuration. It does not read WORKFLOW_VERCEL_* automatically, so pass the environment values yourself when you want a configured World module:

my-world.ts
import { createWorld } from "@workflow/world-vercel";

export default createWorld({
  token: process.env.WORKFLOW_VERCEL_AUTH_TOKEN,
  projectConfig: {
    projectId: "prj_...",
    teamId: "team_...",
    environment: "production",
  },
});
.env
WORKFLOW_TARGET_WORLD="./my-world.ts"

Versioning

On Vercel, workflow runs are pegged to the deployment that started them. This means:

  • Existing workflow runs continue executing on their original deployment, even as new code is deployed
  • New workflow runs start on the latest deployment
  • Code changes won't break in-flight workflows

This ensures long-running workflows complete reliably without being affected by subsequent deployments.

For the full model, including rerunning on latest and explicit upgrade boundaries, see Versioning.

Security

Consumer function security

Workflow handler functions on Vercel are not accessible through public endpoints. During the build step, the Workflow SDK registers the combined flow handler as only reachable by Vercel Queue, using the experimentalTriggers configuration in .vc-config.json:

.vc-config.json (flow handler)
{
  "experimentalTriggers": [
    {
      "type": "queue/v2beta",
      "topic": "__wkf_workflow_*",
      "consumer": "default",
    }
  ]
}

Practically, this means:

  • You don't need to add authentication or authorization logic to workflow handlers
  • Unauthorized requests can never reach workflow or step execution
  • Only messages delivered through Vercel Queues can trigger execution
  • Handlers receive only a message ID that must be retrieved from Vercel's backend, making it impossible to craft custom payloads

The Workflow SDK build step manages this configuration. If you are writing a custom integration, see Framework integrations: Security for more details.

How it works

The Vercel World uses Vercel's infrastructure for workflow execution:

  • Storage: Workflow data is stored in Vercel's cloud with automatic replication and end-to-end encryption
  • Queuing: Steps are distributed across Vercel Functions through Vercel Queues with automatic retries and consumer function security
  • Authentication: OIDC tokens provide secure, automatic authentication

For more details, see the Vercel Workflow documentation.