惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hacker News: Ask HN
Hacker News: Ask HN
O
OpenAI News
Cloudbric
Cloudbric
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
J
Java Code Geeks
Help Net Security
Help Net Security
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
有赞技术团队
有赞技术团队
Security Archives - TechRepublic
Security Archives - TechRepublic
Hugging Face - Blog
Hugging Face - Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
GbyAI
GbyAI
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 司徒正美
T
The Blog of Author Tim Ferriss
人人都是产品经理
人人都是产品经理
H
Help Net Security
Google DeepMind News
Google DeepMind News
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog RSS Feed
W
WeLiveSecurity
Stack Overflow Blog
Stack Overflow Blog
The GitHub Blog
The GitHub Blog
N
Netflix TechBlog - Medium
Jina AI
Jina AI
S
Security @ Cisco Blogs
月光博客
月光博客
Google Online Security Blog
Google Online Security Blog
P
Proofpoint News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
TaoSecurity Blog
TaoSecurity Blog
MongoDB | Blog
MongoDB | Blog
WordPress大学
WordPress大学
F
Fortinet All Blogs
S
Securelist
M
MIT News - Artificial intelligence
V
Vulnerabilities – Threatpost
小众软件
小众软件
T
Tenable Blog
Y
Y Combinator Blog
T
Threat Research - Cisco Blogs
博客园 - 叶小钗
N
News | PayPal Newsroom
A
About on SuperTechFans
C
CERT Recently Published Vulnerability Notes
Cyberwarzone
Cyberwarzone
L
Lohrmann on Cybersecurity

Workflow SDK Documentation

Patterns for Defining Tools Human-in-the-Loop Building Durable AI Agents Queueing User Messages Resumable Streams Sleep, Suspense, and Scheduling Streaming Updates from Tools API Reference Workflow Globals Changelog Resilient run start Cookbook Building a World Deploying Astro Express Fastify Hono Getting Started NestJS Next.js Nitro Nuxt Python SvelteKit Vite corrupted-event-log fetch-in-workflow hook-conflict Errors node-js-module-in-workflow serialization-failed start-invalid-workflow-function step-not-registered timeout-in-workflow webhook-invalid-respond-with-value webhook-response-not-sent workflow-not-registered Errors & Retrying Hooks & Webhooks Idempotency Foundations Serialization Starting Workflows Streaming Versioning How the Directives Work Encryption Event Sourcing Framework Integrations Understanding Directives Migration Guides Migrating from AWS Step Functions Migrating from Inngest Migrating from Temporal Observability Testing Server-Based Testing createHook createWebhook defineHook FatalError fetch getStepMetadata getWorkflowMetadata getWritable workflow RetryableError sleep @workflow/vitest DurableAgent @workflow/ai WorkflowChatTransport getHookByToken getRun getWorld workflow/api resumeHook resumeWebhook Chat Session Modeling runtime-decryption-failed Upgrading Workflows abort-signal-timeout-in-workflow Cancellation How Cancellation Works Internal Serializable AbortController and AbortSignal Eager Processing of Steps & Incremental Event Replay TanStack Start Agent Cancellation Sequential & Parallel Execution Workflow Composition Local World | Workflow SDK Postgres World | Workflow SDK Vercel World | Workflow SDK Migrating from trigger.dev Secure Credential Handling Local World | Workflow SDK Postgres World | Workflow SDK Vercel World | Workflow SDK
Workflows and Steps
2026-05-31 · via Workflow SDK Documentation

Build long-running, stateful application logic that persists progress and resumes after failures.

Workflows (a.k.a. durable functions) are a programming model for building long-running, stateful application logic that can maintain its execution state across restarts, failures, or user events. Unlike traditional serverless functions that lose all state when they terminate, workflows persist their progress and can resume exactly where they left off.

Moreover, workflows let you easily model complex multi-step processes in simple, elegant code. To do this, we introduce two fundamental entities:

  1. Workflow Functions: Functions that orchestrate/organize steps
  2. Step Functions: Functions that carry out the actual work

Directive: "use workflow"

Workflow functions define the entrypoint of a workflow and organize how step functions are called. This type of function does not have access to the Node.js runtime, and usable npm packages are limited.

Although this may seem limiting initially, this feature is important in order to suspend and accurately resume execution of workflows.

It helps to think of the workflow function less like a full JavaScript runtime and more like "stitching together" various steps using conditionals, loops, try/catch handlers, Promise.all, and other language primitives.

export async function processOrderWorkflow(orderId: string) {
  "use workflow"; 

  // Orchestrate multiple steps
  const order = await fetchOrder(orderId);
  const payment = await chargePayment(order);

  return { orderId, status: "completed" };
}

Key Characteristics:

  • Runs in a sandboxed environment without full Node.js access (see Workflow Globals for what's available)
  • All step results are persisted to the event log
  • Must be deterministic to allow resuming after failures

Determinism in the workflow is required to resume the workflow from a suspension. Essentially, the workflow code gets re-run multiple times during its lifecycle, each time using the event log to resume the workflow to the correct spot.

The sandboxed environment that workflows run in already ensures determinism. For instance, Math.random and Date constructors are fixed in workflow runs, so you are safe to use them, and the framework ensures that the values don't change across replays.

Directive: "use step"

Step functions perform the actual work in a workflow and have full runtime access.

async function chargePayment(order: Order) {
  "use step"; 

  // Full Node.js access - use any npm package
  const stripe = new Stripe(process.env.STRIPE_KEY);

  const charge = await stripe.charges.create({
    amount: order.total,
    currency: "usd",
    source: order.paymentToken
  });

  return { chargeId: charge.id };
}

Key Characteristics:

  • Full Node.js runtime and npm package access
  • Automatic retry on errors
  • Results persisted for replay

By default, steps have a maximum of 3 retry attempts before they fail and propagate the error to the workflow. Learn more about errors and retrying in the Errors & Retrying page.

Important: Due to serialization, parameters are passed by value, not by reference. If you pass an object or array to a step and mutate it, those changes will not be visible in the workflow context. Always return modified data from your step functions instead. See Pass-by-Value Semantics for details and examples.

Step functions are primarily meant to be used inside a workflow.

Calling a step from outside a workflow or from another step will essentially run the step in the same process like a normal function (in other words, the use step directive is a no-op). This means you can reuse step functions in other parts of your codebase without needing to duplicate business logic.

async function updateUser(userId: string) {
  "use step";
  await db.insert(...);
}

// Used inside a workflow
export async function userOnboardingWorkflow(userId: string) {
  "use workflow";
  await updateUser(userId);
  // ... more steps
}

// Used directly outside a workflow
export async function POST() {
  await updateUser("123");
  // ... more logic
}

Keep in mind that calling a step function outside of a workflow function will not have retry semantics, nor will it be observable. Additionally, certain workflow-specific functions like getStepMetadata() will throw an error when used inside a step that's called outside a workflow.

Suspension and Resumption

Workflow functions have the ability to automatically suspend while they wait on asynchronous work. While suspended, the workflow's state is stored via the event log and no compute resources are used until the workflow resumes execution.

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.

There are multiple ways a workflow can suspend:

  • Waiting on a step function: the workflow yields while the step runs in the step runtime.
  • Using sleep() to pause for some fixed duration.
  • Awaiting on a promise returned by createWebhook(), which resumes the workflow when an external system passes data into the workflow.
import { sleep, createWebhook } from "workflow";

export async function documentReviewProcess(userId: string) {
  "use workflow";

  await sleep("30d"); // Sleep will suspend without consuming any resources

  // Create a webhook for external workflow resumption
  const webhook = createWebhook();

  // Send the webhook url to some external service or in an email, etc.
  await sendHumanApprovalEmail("Click this link to accept the review", webhook.url)

  const data = await webhook; // The workflow suspends till the URL is resumed

  console.log("Document reviewed!")
}

Basic Structure

The simplest workflow consists of a workflow function and one or more step functions.

// Workflow function (orchestrates the steps)
export async function greetingWorkflow(name: string) {
  "use workflow";

  const message = await greet(name);
  return { message };
}

// Step function (does the actual work)
async function greet(name: string) {
  "use step";

  // Access Node.js APIs
  const message = `Hello ${name} at ${new Date().toISOString()}`;
  console.log(message);
  return message;
}

Project structure

While you can organize workflow and step functions however you like, we find that larger projects benefit from some structure:

You can choose to organize your steps into a single steps.ts file or separate files within a steps folder. The shared folder is a good place to put common steps that are used by multiple workflows.

Splitting up steps and workflows will also help avoid most bundler related bugs with the Workflow SDK.