openbrain
Concepts

Execution

How workflows execute from trigger to completion.

Execution

When a workflow runs, flow orchestrates a multi-step process that flushes real-time state, creates run records, and executes nodes in dependency order using Vercel WDK for durable execution.

Execution overview

The execution pipeline has six steps:

  1. Flush Yjs state — the webapp calls flushCollabState to force the collab server to persist the latest Yjs document to MongoDB, ensuring the executor reads up-to-date nodes and edges
  2. Create run recordsstartWorkflowRun creates a WorkflowRun record and one NodeRun record per node, all with pending status
  3. Set activeRunId — the collab server is notified to set activeRunId in the Yjs runtime map, which triggers UI updates on all connected clients
  4. Execute nodes — the WDK executor processes nodes in topological order, running each node's step function with resolved inputs
  5. Persist outputs — each node's output is written to the NodeRun record in the database, and generated assets (images, videos) are uploaded to R2
  6. Bump runsVersion — after each node completes, updateCollabRuntime bumps the runsVersion counter in Yjs, signaling clients to fetch updated run data

Topological execution

Nodes execute in topological order — a node only runs after all its upstream dependencies have completed. Nodes at the same level (no dependencies on each other) can execute concurrently.

Level 0:  [Text Variable]   [Image Variable]
              │                    │
Level 1:  [Flux Schnell] ─────────┘

Level 2:  [Upscale]

Level 3:  [Preview]

In this example:

  • Level 0: Both variable nodes execute first (no upstream dependencies)
  • Level 1: Flux Schnell waits for both variables, then executes
  • Level 2: Upscale waits for Flux Schnell
  • Level 3: Preview waits for Upscale

Nodes on independent branches execute in parallel. If a workflow has two separate chains that don't share edges, they run simultaneously.

Step functions

Each node's plugin declares a step property that maps to a server-side step function. Step functions use the "use step" directive to mark them as durable WDK steps.

Built-in step functions:

StepDescription
falCalls fal.ai inference API for image/video generation models
ai-gatewayRoutes text generation to Anthropic, OpenAI, Google, or Meta models
shotstackSubmits video rendering jobs to Shotstack
httpMakes arbitrary HTTP requests
jsExecutes user-defined JavaScript in a sandboxed environment
r2-uploadUploads content to Cloudflare R2

Step functions receive the node's resolved inputs (values from connected edges + config values) and return an output object keyed by output handle IDs.

Compute functions

Some nodes execute client-side without a server round-trip. These use compute functions instead of step functions and run instantly in the browser:

ComputeDescription
routerRoutes input to one of several outputs based on a condition
filterPasses or blocks values based on a predicate
promptInterpolates variables into a prompt template
listCollects multiple inputs into a list
concatConcatenates text values

Compute nodes are resolved by computeDerived() during the React render cycle. They do not create NodeRun records and do not appear in run history.

Error handling

When a node fails during execution:

  1. The failed node's NodeRun status is set to error with an error message
  2. All downstream nodes (nodes that depend on the failed node's output) are set to cancelled
  3. Nodes on other branches of the graph that do not depend on the failed node continue executing normally
  4. The overall WorkflowRun status is set to error once all branches have completed or been cancelled
[Text] ──> [Flux Schnell] ──X──> [Upscale] ──> [Preview]
                error            cancelled     cancelled

[Image] ──> [Background Remove] ──> [Save]
                 success             success

In this example, Flux Schnell fails, so Upscale and Preview are cancelled. But Background Remove and Save are on an independent branch and complete successfully.

Asset persistence

When a node produces media output, flow automatically persists it:

Output typeStorageDetails
ImagesCloudflare R2Uploaded as WebP, accessible via R2 public URL with Image Transformations
VideosCloudflare R2 + StreamUploaded to R2 for storage, copied to Cloudflare Stream for playback
AudioCloudflare R2Uploaded in original format
Text / JSONMongoDBStored directly in the NodeRun output field

Asset URLs in the NodeRun.output object point to the persisted R2 location, not the temporary generation URL. This ensures outputs remain accessible after the run completes.

Durable execution

flow uses Vercel WDK (Workflow Development Kit) for durable execution. Each step function is a WDK step, which means:

  • Automatic retries — if a step fails due to a transient error, WDK retries it
  • State persistence — step results are durably stored, so a workflow can resume after a crash
  • Timeout handling — long-running steps (like video rendering) are monitored and timed out gracefully
  • Idempotency — steps are designed to be safely re-executed without side effects

On this page