World / Cloudflare
GitHub

Start here

A workflow is a log you can replay.

A Workflow SDK v5 World built on Cloudflare Workers, Durable Objects and R2. Here is what runs where, why each part exists, and what the measurements actually show.

Your workflow code describes the work. The SDK decides how to execute, suspend and replay it. The World supplies durable storage and message delivery. This implementation puts those pieces in your Cloudflare account, without using the Cloudflare Workflows product.

One run, on CloudflareClick a service to explore itSwipe to explore →
The Cloudflare World’s request and execution pathsThe app reaches a router, which writes to a store shard. Store outbox messages reach queue shards. Runners call the consumer and selected executor. The executor reads and writes run state, streams and snapshots.Your appstart()Router Workerstateless entry pointStore shardsSQLite · ordered eventsQueue shardsreplays / stepsRunnersreplay & step deliveryConsumerdeployment routingExecutor WorkerSDK + workflow bundleRun streams + R2bytes / snapshotsIndex & token shardslists / hook lookup
The app calls start(). The store commits run state and durable publish intent; a queue shard accepts the start. Listing updates happen separately.
Selected pathOther callsLogical components, not individual machines

The diagram shows retained-executor mode. Without a dispatch binding, the consumer runs the flow in the main Worker instead.

Same SDK, different infrastructure

A World is an adapter, not a second workflow language. Ordinary "use workflow" and "use step" functions still compile with the published Workflow SDK. The SDK owns deterministic replay, step behavior, hooks and sleeps. Our World implements the interfaces those features call.

A normal Workflow SDK workflow
export async function order(id: string) {
  "use workflow";
  const receipt = await charge(id);
  await sendReceipt(receipt);
  return receipt;
}

async function charge(id: string) {
  "use step";
  // Call your payment API with a stable idempotency key.
  return { id, paid: true };
}

The durable record is the event log. After an interruption, core reconstructs workflow decisions from that log. A step result already in history is read back instead of running the body again as part of replay. A retried step attempt can still repeat an external side effect.

Three jobs, kept separate

JobOur implementationWhy separate it?
RememberStore shards commit events and materialized state to SQLite. Large bytes go to R2.A workflow survives the request and the process that started it.
DeliverQueue shards persist starts, continuations, delays and retries.The caller can disconnect without owning the run’s progress.
ExecuteRunners call the SDK flow handler, optionally in a retained executor Worker.Workflow CPU and slow I/O do not run on the queue object itself.

The World client is a library in the caller, not another deployed service. Indexes, token registries and streams support those three jobs; they are not all separate Worker deployments either.

Recorded results, not promises

5,082/s

Run creations

100k burst, build 8cddcbd
30,000

Sequential steps in one run

QuickJS, build adff891
32 MiB

Encoded stream chunk cap

Raw allowance depends on framing

Current probes passed 30k parallel steps on QuickJS and 2.5k native; 35k and 3k respectively hit executor memory limits. The SDK also exhausted memory while reading 2 GiB in one step. The benchmarks page gives the workload, failures and limits of those conclusions.

Read the system in order

Sources and implementation

Repository links may require access. Vercel links point to public source or published documentation. Logical API names do not establish backend internals.

World for Cloudflare · Workflow SDK v5Source, measurements, and the limits between them.

Browse topics or type to search

IntroductionA Workflow SDK v5 World built on Cloudflare Workers, Durable Objects and R2. Here is what runs where, why each part exists, and what the measurements actually show.Same SDK, different infrastructureA workflow is a log you can replay.Three jobs, kept separateA workflow is a log you can replay.Recorded results, not promisesA workflow is a log you can replay.Read the system in orderA workflow is a log you can replay.The architectureAn ordered store for each run, delivery capacity shared across shards, and execution kept off the queue objects.Where everything livesThe architectureOrder state, distribute executionThe architectureRouting without a global directoryThe architectureWhat the design buys, and costsThe architectureLife of a requestFollow the ordinary static-workflow start path, then the deliveries that turn the stored intent into completed work.Our World: accepting the runLife of a requestOur World: delivering and runningLife of a requestVercel: the corresponding pathLife of a requestWhat a response does and does not guaranteeLife of a requestEvery service, explainedWhat each component owns, why it exists, how it helps, and the limit it introduces. These are logical roles, not twelve separate deployed services.Router Worker and World clientEvery service, explainedRun-store shardsEvery service, explainedQueue shardsEvery service, explainedWorkflow runners and step runnersEvery service, explainedConsumer and retained executor WorkersEvery service, explainedIndex shardsEvery service, explainedHook token registriesEvery service, explainedRun streams and VM snapshotsEvery service, explainedR2 payloads and dead lettersEvery service, explainedAlarms and cron recoveryEvery service, explainedState and deliveryHow an event becomes durable work, why the outbox exists, and where transactions stop.The event is the durable recordState and deliveryWhy commit an outbox?State and deliveryHook claims cross transaction boundariesState and deliveryAt-least-once means side effects can repeatState and deliveryRetries, limits and recoveryState and deliveryExecution and replayWorkflow decisions execute inside a deterministic runtime. Step bodies do the I/O outside it. QuickJS and the native engine trade replay work for memory and compatibility.Workflow code is not step codeExecution and replayQuickJS is our defaultExecution and replayThe native engine uses a build-time shimExecution and replayWhat the replay numbers meanExecution and replayShards and placementSpread independent runs, preserve old routing, and keep state near execution where possible. More shards are capacity, not free speed.Time picks the epoch, hash picks the shardShards and placementA location hint is a hintShards and placementWhy creation throughput is highShards and placementMany runs scale better than one enormous runShards and placementPayloads and byte streamsUse values for control data and byte streams for bulk data. Offloading to R2 removes storage-message pressure, not every memory limit.A value still has to fit in memoryPayloads and byte streamsPass a handle, then move bytes incrementallyPayloads and byte streamsThe producer must outlive the step resultPayloads and byte streamsThe current multi-GiB reader problemPayloads and byte streamsCompared with VercelTwo implementations of the same World contract. We can inspect Vercel’s public adapter, not the internals behind its managed APIs.The services Vercel’s public client usesCompared with VercelThe same jobs, different ownersCompared with VercelHow their transport worksCompared with VercelWhere our design helpsCompared with VercelRead the Vercel limits with their runtime contextCompared with VercelMeasurements and limitsRecorded Workers results, the workload behind each number, and the failures that keep these from being unlimited-capacity claims.Latest regression checkMeasurements and limitsCreation is not completionMeasurements and limitsExecution resultsMeasurements and limitsLimits are not all the same kind of numberMeasurements and limitsKnown failure pointsMeasurements and limitsRun the probesMeasurements and limitsIdentity and deploymentsBindings authorize internal access. Your application protects public routes. Encryption and retained release routing solve separate problems.Internal calls use capabilitiesIdentity and deploymentsEncryption has a narrower scope than “all data”Identity and deploymentsKeep the code that owns old historyIdentity and deploymentsHow Vercel’s identity differsIdentity and deploymentsBuild, deploy and operateThe repository root is an example application. The reusable World lives in packages/world-cloudflare. Deploy the minimal mode first, then add retained executors if you need them.Start with the exampleBuild, deploy and operateKnow which config changes affect old runsBuild, deploy and operateDeploy state first, then the retained executorBuild, deploy and operateTest the adapter, the SDK and the deploymentBuild, deploy and operateOperational work still leftBuild, deploy and operate
Local search. Nothing sent to a server.Esc to close
Documentation