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

推荐订阅源

月光博客
月光博客
小众软件
小众软件
爱范儿
爱范儿
Y
Y Combinator Blog
博客园 - Franky
美团技术团队
博客园 - 【当耐特】
The Cloudflare Blog
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
Jina AI
Jina AI
IT之家
IT之家
人人都是产品经理
人人都是产品经理
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
大猫的无限游戏
大猫的无限游戏
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 聂微东
WordPress大学
WordPress大学
V
Visual Studio Blog
博客园_首页
阮一峰的网络日志
阮一峰的网络日志
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
有赞技术团队
有赞技术团队

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
Idempotency
2026-05-31 · via Workflow SDK Documentation

Ensure operations can be safely retried without producing duplicate side effects.

Idempotency is a property of an operation that ensures it can be safely retried without producing duplicate side effects.

In distributed systems (calling external APIs), it is not always possible to ensure an operation has only been performed once just by seeing if it succeeds. Consider a payment API that charges the user $10, but due to network failures, the confirmation response is lost. When the step retries (because the previous attempt was considered a failure), it will charge the user again.

To prevent this, many external APIs support idempotency keys. An idempotency key is a unique identifier for an operation that can be used to deduplicate requests.

Every step invocation has a stable stepId that stays the same across retries. Use it as the idempotency key when calling third-party APIs.

import { getStepMetadata } from "workflow";

async function chargeUser(userId: string, amount: number) {
  "use step";

  const { stepId } = getStepMetadata();

  // Example: Stripe-style idempotency key
  // This guarantees only one charge is created even if the step retries
  await stripe.charges.create(
    {
      amount,
      currency: "usd",
      customer: userId,
    },
    {
      idempotencyKey: stepId, 
    }
  );
}

Why this works:

  • Stable across retries: stepId does not change between attempts.
  • Globally unique per step: Fulfills the uniqueness requirement for an idempotency key.
  • Always provide idempotency keys to external side effects that are not idempotent inside steps (payments, emails, SMS, queues).
  • Prefer stepId as your key; it is stable across retries and unique per step.
  • Keep keys deterministic; avoid including timestamps or attempt counters.
  • Handle 409/conflict responses gracefully; treat them as success if the prior attempt completed.