UNPKG

workflow

Version:

Workflow SDK - Build durable, resilient, and observable workflows

124 lines (94 loc) • 11.2 kB
--- title: Workflow SDK vs Temporal description: 'How the Workflow SDK compares to Temporal: execution model, where workers run, versioning, AI agents, pricing, and a concept-mapping migration guide.' type: conceptual summary: Temporal is a mature, language-agnostic durable-execution platform where you run the workers. The Workflow SDK runs in your existing app and pins runs to immutable deployments. prerequisites: - /docs/foundations/workflows-and-steps related: - /docs/foundations/hooks - /docs/foundations/streaming - /docs/ai - /worlds/vercel --- [Temporal](https://temporal.io) is a durable-execution platform with seven language SDKs and large-scale production use. Temporal and the Workflow SDK share the same core model of durable orchestration through event-sourced replay. The operational differences are **where your code runs, how you version it, and how it streams to clients.** <Callout type="info"> **Choose the Workflow SDK** when you want durable execution inside your existing TypeScript app with no additional infrastructure to operate, deployment-pinned versioning, and native streaming for AI apps. **Choose Temporal** when you need SDKs for languages such as Go and Java, want a self-hostable control plane you own, or are standardizing a large organization on one orchestration backend across many languages. </Callout> ## At a glance | | Workflow SDK | Temporal | | --- | --- | --- | | **Category** | Open-source durable-functions SDK; managed on Vercel or self-hosted | Durable-execution platform; Temporal Cloud or self-hosted cluster | | **Durability model** | Event log + deterministic replay (`"use workflow"` orchestrators, `"use step"` functions) | Event-sourced replay (Workflows + Activities). Same model: `"use workflow"` ≈ Workflow, `"use step"` ≈ Activity | | **Languages** | TypeScript / JavaScript (Python beta) | Go, Java, TypeScript, Python, .NET, PHP, Ruby (7 SDKs) | | **Where execution runs** | Orchestration + execution + observability co-located on your platform; private networking and end-to-end (E2E) encryption included on Vercel | **You run and scale your own Workers.** Temporal Cloud hosts orchestration only; workers connect outbound over the public internet (PrivateLink optional) | | **Versioning** | Runs pinned to their immutable deployment, safe by default; opt-in `deploymentId: 'latest'` to upgrade | Editing workflow code can break in-flight runs (non-determinism errors); evolve safely via patch APIs or Worker Versioning (keep old worker fleets draining) | | **AI SDK & agents** | `WorkflowAgent` ships in the AI SDK; durable agent loop; **native resumable streaming** (`getWritable`/`getReadable`, `WorkflowChatTransport`) | First-party `@temporalio/ai-sdk` and "Workflow Streams", both **Public Preview**; streaming rides on Signals/Updates (batched, history-bound) | | **Security** | Zero-config per-run AES-256-GCM E2E encryption by default; platform security is per World (the Vercel World inherits Vercel's security posture) | Workers run your code on your infrastructure (never enters Temporal's plane); client-side E2E via a Codec Server you operate. Cloud: SOC 2 II, HIPAA, GDPR | | **Performance** | No-penalty resume; serverless scale-to-zero (true suspension); up to 100,000 concurrency on Vercel | Self-managed workers are long-running; Cloud namespace default 500 actions/sec (auto-scales) | | **Portability** | Apache-2.0 SDK; World abstraction swaps storage/queue/streams independently | MIT server; pluggable persistence (Cassandra/Postgres/MySQL), but an opinionated monolithic backend you run or pay for | | **Pricing** | SDK free; pay your platform (Vercel: events + data) or only your infrastructure if self-hosted | Self-host = free software; Temporal Cloud bills per Action (from $50 per million) + storage | | **Limits** | No run/sleep cap; 10,000 steps, 50 MB payload, 2 GB/run ([Vercel World limits](https://vercel.com/docs/workflows/pricing)) | No run cap (Continue-As-New for long histories); event history capped at 51,200 events / 50 MB; 2 MB payloads | **What the limits mean in practice**: Temporal caps payloads at 2 MB and event history at 51,200 events. A model context, tool transcript, or embedding batch that exceeds 2 MB requires external blob storage and claim-check plumbing. Long agent loops must use Continue-As-New before the history fills. The [Vercel World limits](https://vercel.com/docs/workflows/pricing) (50 MB payloads, 2 GB of state per run, and no run or sleep caps) provide more space for contexts in the run itself. ## The biggest difference: what you operate Temporal Cloud manages the durable engine, but **you still build, deploy, and scale a fleet of Workers** that poll task queues and run your Workflow and Activity code. Those workers connect *out* to Temporal Cloud, typically over the public internet (AWS PrivateLink and Google Cloud Private Service Connect are available as same-region options). To make encrypted payloads readable in the Web UI, you must run a **Codec Server**. With the Workflow SDK on Vercel, orchestration, execution, and observability are co-located on one platform with internal networking, and per-run E2E encryption is on by default with no codec server to run. There are no workers, task queues, or a control plane to operate. (Self-hosting via the [Postgres World](/worlds/postgres) is the closest analog to running your own Temporal cluster.) ## Versioning This is where the two differ most in day-to-day risk. Because both replay code against history, *changing* workflow code mid-flight is the hazard. - **Temporal**: Editing a workflow can produce a non-determinism error that breaks or stalls open executions. You can evolve workflows with **patch APIs** (`patched()` / `GetVersion()`, which accumulate patch branches) or **Worker Versioning** (Build IDs / Worker Deployments pin workflows to a build and keep the old worker fleet running until it drains). You must manage this process for every long-running workflow. - **Workflow SDK**: Runs are **pinned to the immutable deployment that started them**. Shipping new code never touches in-flight runs because they keep replaying against the exact code they began on. Upgrading a run is explicit and opt-in (start it with `deploymentId: 'latest'`, or self-restart at a checkpoint). This model requires no patch branches or draining worker fleets. ## AI agents and streaming Both target AI agents, but the integration depth differs. The Workflow SDK's `WorkflowAgent` is a first-class construct **inside the AI SDK** (`@ai-sdk/workflow`): the agent loop becomes a durable workflow, each tool `execute` marked `"use step"` is an auto-retried durable step, and partial output streams through [durable, resumable streams](/docs/ai/resumable-streams) that survive reconnects and cold starts. Temporal ships a first-party `@temporalio/ai-sdk` plugin and a "Workflow Streams" library, but both are **Public Preview**, and streaming is built on Signals/Updates: every chunk is written to history, so it's batched rather than per-token. ## Migrating from Temporal The model maps closely. Keep your orchestration logic; drop the workers, task queues, and activity modules. | Temporal | Workflow SDK | Note | | --- | --- | --- | | Workflow Definition / Execution | `"use workflow"` function started with `start()` | Orchestration stays in the workflow function. | | Activity | `"use step"` function | Side effects and Node.js access live in steps. | | Worker + Task Queue | Managed execution | No worker fleet or polling loop to operate. | | Signal | `createHook()` / `createWebhook()` | Hooks for typed resume signals; webhooks for HTTP callbacks. | | Query | `getWritable({ namespace: 'status' })` stream | Stream status durably; clients read the stream instead of polling. | | Child Workflow | Call [`start()`](/docs/foundations/starting-workflows) directly from the workflow | Child runs are tagged with `$parentRunId` / `$rootRunId` automatically. | | Activity retry policy | `maxRetries`, `RetryableError`, `FatalError` | Retries live at the step boundary. See [Errors & Retrying](/docs/foundations/errors-and-retries). | | Search attributes / visibility queries | [`setAttributes()`](/docs/api-reference/workflow/set-attributes) / `attributes` option on `start()` | Filter runs by `key=value`. See [Attributes](/docs/observability/attributes). | | Event History | Workflow event log / run timeline | Same durable replay; built-in observability UI. | A minimal translation, where the orchestrator loses `proxyActivities` and becomes plain TypeScript: ```typescript title="workflows/order.ts" export async function processOrder(orderId: string) { 'use workflow'; // [!code highlight] await chargePayment(orderId); return { orderId, status: 'completed' }; } async function chargePayment(orderId: string) { 'use step'; // [!code highlight] await fetch(`https://example.com/api/orders/${orderId}/charge`, { method: 'POST' }); } ``` Signals become hooks, where one `createHook()` + `await` replaces a signal definition, handler, and `condition()` guard: ```typescript title="workflows/refund.ts" import { createHook } from 'workflow'; export async function refundWorkflow(refundId: string) { 'use workflow'; using approval = createHook<{ approved: boolean }>({ token: `refund:${refundId}:approval`, // [!code highlight] }); const { approved } = await approval; // suspends durably until resumed return { refundId, approved }; } ``` <Callout type="info"> Install the migration skill to translate a Temporal app automatically: ```bash npx skills add https://github.com/vercel/workflow --skill migrating-to-workflow-sdk ``` </Callout> ### Temporal features without a direct Workflow SDK equivalent Each row is a Temporal capability the Workflow SDK does not replicate one-to-one, paired with how to cover it on the Workflow SDK side: | Temporal feature | How to cover it with the Workflow SDK | | --- | --- | | Per-activity timeouts (`startToCloseTimeout`, etc.) | Enforce deadlines inside a step with `AbortSignal.timeout(ms)`, or wrap a call in `Promise.race(step(), sleep('5m'))` | | Declarative retry policy (`backoffCoefficient`, `nonRetryableErrorTypes`, `maximumAttempts`) | The Workflow SDK expresses the same policies idiomatically in code instead of a config object: cap attempts with [`maxRetries`](/docs/foundations/errors-and-retries#default-retrying), mark errors non-retryable with [`FatalError`](/docs/api-reference/workflow/fatal-error), and derive any backoff curve from [`getStepMetadata().attempt`](/docs/api-reference/workflow/get-step-metadata) via [`RetryableError`](/docs/api-reference/workflow/retryable-error)'s `retryAfter`. See the [exponential backoff example](/docs/foundations/errors-and-retries#advanced-example). | | Polyglot workers | The Workflow SDK is TypeScript-first (Python in beta); for Go/Java/etc. in the same orchestrator, Temporal remains the better fit | --- *Compiled from public documentation. Verify current Temporal pricing, limits, and preview-feature status against [temporal.io/docs](https://docs.temporal.io). Not based on head-to-head benchmarks.*