cloudflare-durable-objects

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Cloudflare Durable Objects

Cloudflare Durable Objects

Status: Production Ready ✅ Last Updated: 2025-11-25 Dependencies: cloudflare-worker-base (recommended) Latest Versions: wrangler@4.81.0+, @cloudflare/workers-types@4.20260408.0+ Official Docs: https://developers.cloudflare.com/durable-objects/
状态:已就绪可用于生产 ✅ 最后更新:2025-11-25 依赖:cloudflare-worker-base(推荐) 最新版本:wrangler@4.81.0+, @cloudflare/workers-types@4.20260408.0+ 官方文档https://developers.cloudflare.com/durable-objects/

Table of Contents

目录

What are Durable Objects?

什么是Durable Objects?

Globally unique, stateful objects with single-point coordination, strong consistency (ACID), WebSocket Hibernation (thousands of connections), SQLite storage (1GB), and alarms API.

Use for: Chat rooms, multiplayer games, rate limiting, session management, leader election, stateful workflows

全局唯一的有状态对象,具备单点协调、强一致性(ACID)、WebSocket休眠(支持数千连接)、SQLite存储(1GB容量)以及告警API。

适用场景:聊天室、多人游戏、限流、会话管理、主节点选举、有状态工作流

Quick Start (10 Minutes)

快速入门(10分钟)

Option 1: Scaffold New DO Project

选项1:搭建新的DO项目

bash
npm create cloudflare@latest my-durable-app -- \
  --template=cloudflare/durable-objects-template --ts --git --deploy false
cd my-durable-app && bun install && npm run dev
bash
npm create cloudflare@latest my-durable-app -- \\
  --template=cloudflare/durable-objects-template --ts --git --deploy false
cd my-durable-app && bun install && npm run dev

Option 2: Add to Existing Worker

选项2:添加至现有Worker

1. Install types:
bash
bun add -d @cloudflare/workers-types
2. Create DO class (
src/counter.ts
):
typescript
import { DurableObject } from 'cloudflare:workers';

export class Counter extends DurableObject {
  async increment(): Promise<number> {
    let value: number = (await this.ctx.storage.get('value')) || 0;
    await this.ctx.storage.put('value', ++value);
    return value;
  }
}

export default Counter;  // CRITICAL
3. Configure (
wrangler.jsonc
):
jsonc
{
  "durable_objects": {
    "bindings": [{ "name": "COUNTER", "class_name": "Counter" }]
  },
  "migrations": [
    { "tag": "v1", "new_sqlite_classes": ["Counter"] }
  ]
}
4. Call from Worker (
src/index.ts
):
typescript
import { Counter } from './counter';

interface Env {
  COUNTER: DurableObjectNamespace<Counter>;
}

export { Counter };

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const stub = env.COUNTER.getByName('global-counter');
    return new Response(`Count: ${await stub.increment()}`);
  },
};
Deploy:
bash
bunx wrangler deploy

1. 安装类型定义
bash
bun add -d @cloudflare/workers-types
2. 创建DO类
src/counter.ts
):
typescript
import { DurableObject } from 'cloudflare:workers';

export class Counter extends DurableObject {
  async increment(): Promise<number> {
    let value: number = (await this.ctx.storage.get('value')) || 0;
    await this.ctx.storage.put('value', ++value);
    return value;
  }
}

export default Counter;  // 至关重要
3. 配置
wrangler.jsonc
):
jsonc
{
  "durable_objects": {
    "bindings": [{ "name": "COUNTER", "class_name": "Counter" }]
  },
  "migrations": [
    { "tag": "v1", "new_sqlite_classes": ["Counter"] }
  ]
}
4. 从Worker调用
src/index.ts
):
typescript
import { Counter } from './counter';

interface Env {
  COUNTER: DurableObjectNamespace<Counter>;
}

export { Counter };

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const stub = env.COUNTER.getByName('global-counter');
    return new Response(`Count: ${await stub.increment()}`);
  },
};
部署
bash
bunx wrangler deploy

Available Commands

可用命令

Use these interactive commands for guided workflows:
  • /do-setup
    - Initialize new DO project with interactive setup wizard
    • Choose storage backend (SQL, KV, both)
    • Select use case pattern (WebSocket, Sessions, Rate Limiting, etc.)
    • Optional Vitest testing setup
    • Generates complete DO implementation
  • /do-migrate
    - Interactive migration assistant
    • New class creation (new_sqlite_classes, new_classes)
    • Rename existing classes (renamed_classes)
    • Delete classes with safety confirmations (deleted_classes)
    • Transfer classes between scripts (transferred_classes)
    • Auto-increments migration tags (v1, v2, v3...)
  • /do-debug
    - Step-by-step debugging workflow
    • Detects error categories (deployment, runtime, performance, etc.)
    • Runs diagnostic checks on configuration and code
    • Provides specific fixes with code examples
    • Guides local testing and production verification
  • /do-patterns
    - Pattern selection wizard
    • Recommends DO pattern based on use case
    • Supports WebSocket, Rate Limiting, Sessions, Analytics, Leader Election
    • Generates complete pattern implementation
    • Provides best practices and optimization tips
  • /do-optimize
    - Performance optimization assistant
    • Analyzes existing DO code for bottlenecks
    • Provides targeted optimization recommendations
    • Covers constructor, queries, WebSocket, memory, alarms
    • Measures performance improvements
使用以下交互式命令完成引导式工作流:
  • /do-setup
    - 交互式向导初始化新DO项目
    • 选择存储后端(SQL、KV或两者皆选)
    • 选择用例模式(WebSocket、会话、限流等)
    • 可选Vitest测试环境搭建
    • 生成完整的DO实现代码
  • /do-migrate
    - 交互式迁移助手
    • 新建类(new_sqlite_classes、new_classes)
    • 重命名现有类(renamed_classes)
    • 安全确认后删除类(deleted_classes)
    • 在脚本间转移类(transferred_classes)
    • 自动递增迁移标签(v1、v2、v3...)
  • /do-debug
    - 分步调试工作流
    • 检测错误类别(部署、运行时、性能等)
    • 对配置和代码运行诊断检查
    • 提供带代码示例的具体修复方案
    • 指导本地测试与生产环境验证
  • /do-patterns
    - 模式选择向导
    • 根据用例推荐DO模式
    • 支持WebSocket、限流、会话、分析、主节点选举
    • 生成完整的模式实现代码
    • 提供最佳实践与优化建议
  • /do-optimize
    - 性能优化助手
    • 分析现有DO代码的瓶颈
    • 提供针对性的优化建议
    • 覆盖构造函数、查询、WebSocket、内存、告警等场景
    • 衡量性能提升效果

Autonomous Agents

自主代理

These agents work autonomously without user interaction:
  • do-debugger
    - Automatic error detection and fixing
    • Validates wrangler.jsonc configuration
    • Detects 16+ common DO errors
    • Applies fixes automatically with backups
    • Tests fixes before reporting
  • do-setup-assistant
    - Automatic project scaffolding
    • Analyzes user requirements from natural language
    • Generates complete DO implementation
    • Creates tests, documentation, validation
    • Supports all use case patterns
  • do-pattern-implementer
    - Production pattern implementation
    • Analyzes existing DO code
    • Recommends patterns by priority
    • Implements TTL cleanup, RPC metadata, SQL indexes, etc.
    • Generates pattern-specific tests

以下代理无需用户交互即可自主运行:
  • do-debugger
    - 自动错误检测与修复
    • 验证wrangler.jsonc配置
    • 检测16+种常见DO错误
    • 自动应用修复并备份原代码
    • 报告前先测试修复效果
  • do-setup-assistant
    - 自动项目搭建
    • 从自然语言分析用户需求
    • 生成完整的DO实现代码
    • 创建测试用例、文档与验证逻辑
    • 支持所有用例模式
  • do-pattern-implementer
    - 生产级模式实现
    • 分析现有DO代码
    • 按优先级推荐模式
    • 实现TTL清理、RPC元数据、SQL索引等功能
    • 生成模式专属测试用例

When to Load References

何时加载参考文档

Load immediately when user mentions:
  • state-api-reference.md
    → "storage", "sql", "database", "query", "get/put", "KV", "1GB limit"
  • websocket-hibernation.md
    → "websocket", "real-time", "chat", "hibernation", "serializeAttachment"
  • alarms-api.md
    → "alarms", "scheduled tasks", "cron", "periodic", "batch processing"
  • rpc-patterns.md
    → "RPC", "fetch", "HTTP", "methods", "routing"
  • rpc-metadata.md
    → "RpcTarget", "metadata", "DO name", "idFromName access"
  • stubs-routing.md
    → "stubs", "idFromName", "newUniqueId", "location hints", "jurisdiction"
  • migrations-guide.md
    → "migrations", "rename", "delete", "transfer", "schema changes"
  • migration-cheatsheet.md
    → "migration quick reference", "migration types", "common migrations"
  • common-patterns.md
    → "patterns", "examples", "rate limiting", "sessions", "leader election"
  • vitest-testing.md
    → "test", "testing", "vitest", "unit test", "@cloudflare/vitest-pool-workers"
  • gradual-deployments.md
    → "gradual", "deployment", "traffic split", "rollout", "canary"
  • typescript-config.md
    → "TypeScript", "types", "tsconfig", "wrangler.jsonc", "bindings"
  • advanced-sql-patterns.md
    → "CTE", "window functions", "FTS5", "full-text search", "JSON functions", "complex SQL"
  • security-best-practices.md
    → "security", "authentication", "authorization", "SQL injection", "CORS", "encryption", "rate limiting"
  • error-codes.md
    → "error codes", "error catalog", "specific error", "E001", "troubleshooting"
  • top-errors.md
    → errors, "not working", debugging, "binding not found"
Load proactively when:
  • Building new feature → Load relevant pattern from
    common-patterns.md
  • Debugging issue → Load
    error-codes.md
    for specific errors, then
    top-errors.md
  • Implementing WebSocket → Load
    websocket-hibernation.md
    before coding
  • Setting up storage → Load
    state-api-reference.md
    for SQL/KV APIs
  • Complex SQL queries → Load
    advanced-sql-patterns.md
    for CTEs, window functions, FTS5
  • Security review → Load
    security-best-practices.md
    for authentication, authorization, SQL injection prevention
  • Creating first DO → Load
    stubs-routing.md
    for ID methods
  • Writing tests → Load
    vitest-testing.md
    for testing patterns
  • Planning deployment → Load
    gradual-deployments.md
    for rollout strategy
  • Migration needed → Load
    migration-cheatsheet.md
    for quick reference
  • Using DO name inside DO → Load
    rpc-metadata.md
    for RpcTarget pattern
  • TypeScript configuration → Load
    typescript-config.md
    for setup

当用户提及以下内容时立即加载
  • state-api-reference.md
    → "存储"、"sql"、"数据库"、"查询"、"get/put"、"KV"、"1GB限制"
  • websocket-hibernation.md
    → "websocket"、"实时"、"聊天"、"休眠"、"serializeAttachment"
  • alarms-api.md
    → "告警"、"定时任务"、"cron"、"周期性"、"批量处理"
  • rpc-patterns.md
    → "RPC"、"fetch"、"HTTP"、"方法"、"路由"
  • rpc-metadata.md
    → "RpcTarget"、"元数据"、"DO名称"、"idFromName访问"
  • stubs-routing.md
    → "存根"、"idFromName"、"newUniqueId"、"位置提示"、"管辖区域"
  • migrations-guide.md
    → "迁移"、"重命名"、"删除"、"转移"、" schema变更"
  • migration-cheatsheet.md
    → "迁移速查"、"迁移类型"、"常见迁移场景"
  • common-patterns.md
    → "模式"、"示例"、"限流"、"会话"、"主节点选举"
  • vitest-testing.md
    → "测试"、"vitest"、"单元测试"、"@cloudflare/vitest-pool-workers"
  • gradual-deployments.md
    → "渐进式"、"部署"、"流量拆分"、"滚动发布"、"金丝雀发布"
  • typescript-config.md
    → "TypeScript"、"类型定义"、"tsconfig"、"wrangler.jsonc"、"绑定"
  • advanced-sql-patterns.md
    → "CTE"、"窗口函数"、"FTS5"、"全文搜索"、"JSON函数"、"复杂SQL"
  • security-best-practices.md
    → "安全"、"身份验证"、"授权"、"SQL注入"、"CORS"、"加密"、"限流"
  • error-codes.md
    → "错误码"、"错误目录"、"特定错误"、"E001"、"故障排查"
  • top-errors.md
    → "错误"、"无法运行"、"调试"、"绑定未找到"
以下场景主动加载
  • 构建新功能 → 从
    common-patterns.md
    加载相关模式
  • 调试问题 → 针对特定错误加载
    error-codes.md
    ,再加载
    top-errors.md
  • 实现WebSocket → 编码前加载
    websocket-hibernation.md
  • 设置存储 → 加载
    state-api-reference.md
    了解SQL/KV API
  • 复杂SQL查询 → 加载
    advanced-sql-patterns.md
    了解CTE、窗口函数、FTS5
  • 安全审查 → 加载
    security-best-practices.md
    了解身份验证、授权、SQL注入防护
  • 创建首个DO → 加载
    stubs-routing.md
    了解ID生成方法
  • 编写测试 → 加载
    vitest-testing.md
    了解测试模式
  • 规划部署 → 加载
    gradual-deployments.md
    了解发布策略
  • 需要迁移 → 加载
    migration-cheatsheet.md
    获取速查指南
  • 在DO内部使用DO名称 → 加载
    rpc-metadata.md
    了解RpcTarget模式
  • TypeScript配置 → 加载
    typescript-config.md
    了解设置方法

Durable Object Class Structure

Durable Object类结构

All DOs extend
DurableObject
and MUST be exported:
typescript
import { DurableObject } from 'cloudflare:workers';

export class MyDO extends DurableObject {
  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);  // Required first line
    // Keep minimal - heavy work blocks hibernation
    ctx.blockConcurrencyWhile(async () => {
      // Load from storage before handling requests
    });
  }

  async myMethod(): Promise<string> {  // RPC method (recommended)
    return 'Hello!';
  }
}

export default MyDO;  // CRITICAL: Must export
this.ctx
provides:
storage
(SQL/KV),
id
(unique ID),
waitUntil()
,
acceptWebSocket()

所有DO都需继承
DurableObject
必须导出
typescript
import { DurableObject } from 'cloudflare:workers';

export class MyDO extends DurableObject {
  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);  // 必须是第一行代码
    // 保持精简 - 繁重操作会阻止休眠
    ctx.blockConcurrencyWhile(async () => {
      // 处理请求前从存储加载数据
    });
  }

  async myMethod(): Promise<string> {  // RPC方法(推荐)
    return 'Hello!';
  }
}

export default MyDO;  // 至关重要:必须导出
this.ctx
提供
storage
(SQL/KV)、
id
(唯一ID)、
waitUntil()
acceptWebSocket()

State API - Persistent Storage

状态API - 持久化存储

Durable Objects provide two storage options:
SQL API (SQLite backend, recommended):
  • Access via
    ctx.storage.sql
  • Up to 1GB storage per instance
  • SQL queries with transactions, indexes, cursors
  • Atomic operations (deleteAll is all-or-nothing)
  • Use
    new_sqlite_classes
    in migrations
Key-Value API (available on both backends):
  • Access via
    ctx.storage
    (get/put/delete/list)
  • Simple key-value operations
  • Async transactions supported
  • 128MB limit on KV backend, 1GB on SQLite
Quick example:
typescript
export class Counter extends DurableObject {
  sql: SqlStorage;

  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
    this.sql = ctx.storage.sql;
    this.sql.exec('CREATE TABLE IF NOT EXISTS counts (key TEXT PRIMARY KEY, value INTEGER)');
  }

  async increment(): Promise<number> {
    this.sql.exec('INSERT OR REPLACE INTO counts (key, value) VALUES (?, ?)', 'count', 1);
    return this.sql.exec('SELECT value FROM counts WHERE key = ?', 'count').one<{value: number}>().value;
  }
}
Load
references/state-api-reference.md
for complete SQL and KV API documentation, cursor operations, transactions, parameterized queries, storage limits, and migration patterns.

Durable Objects提供两种存储选项:
SQL API(SQLite后端,推荐):
  • 通过
    ctx.storage.sql
    访问
  • 每个实例最多支持1GB存储
  • 支持带事务、索引、游标SQL查询
  • 原子操作(deleteAll为全有或全无)
  • 迁移时使用
    new_sqlite_classes
键值API(两种后端均支持):
  • 通过
    ctx.storage
    访问(get/put/delete/list)
  • 简单键值操作
  • 支持异步事务
  • KV后端限制128MB,SQLite后端限制1GB
快速示例
typescript
export class Counter extends DurableObject {
  sql: SqlStorage;

  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
    this.sql = ctx.storage.sql;
    this.sql.exec('CREATE TABLE IF NOT EXISTS counts (key TEXT PRIMARY KEY, value INTEGER)');
  }

  async increment(): Promise<number> {
    this.sql.exec('INSERT OR REPLACE INTO counts (key, value) VALUES (?, ?)', 'count', 1);
    return this.sql.exec('SELECT value FROM counts WHERE key = ?', 'count').one<{value: number}>().value;
  }
}
加载
references/state-api-reference.md
获取完整的SQL与KV API文档、游标操作、事务、参数化查询、存储限制及迁移模式。

WebSocket Hibernation API

WebSocket休眠API

Handle thousands of WebSocket connections per DO instance with automatic hibernation when idle (~10s no activity), saving duration costs. Connections stay open at the edge while DO sleeps.
CRITICAL Rules:
  • ✅ Use
    ctx.acceptWebSocket(server)
    (enables hibernation)
  • ✅ Use
    ws.serializeAttachment(data)
    to persist metadata across hibernation
  • ✅ Restore connections in constructor with
    ctx.getWebSockets()
  • ❌ Don't use
    ws.accept()
    (standard API, no hibernation)
  • ❌ Don't use
    setTimeout
    /
    setInterval
    (prevents hibernation)
Handler methods:
webSocketMessage()
,
webSocketClose()
,
webSocketError()
Quick pattern:
typescript
export class ChatRoom extends DurableObject {
  sessions: Map<WebSocket, any>;

  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
    this.sessions = new Map();
    // Restore connections after hibernation
    ctx.getWebSockets().forEach(ws => {
      this.sessions.set(ws, ws.deserializeAttachment());
    });
  }

  async fetch(request: Request): Promise<Response> {
    const pair = new WebSocketPair();
    const [client, server] = Object.values(pair);

    this.ctx.acceptWebSocket(server);  // ← Enables hibernation
    server.serializeAttachment({ userId: 'alice' });  // ← Persists across hibernation
    this.sessions.set(server, { userId: 'alice' });

    return new Response(null, { status: 101, webSocket: client });
  }

  async webSocketMessage(ws: WebSocket, message: string): Promise<void> {
    const session = this.sessions.get(ws);
    // Broadcast to all
    this.sessions.forEach((_, w) => w.send(message));
  }
}
Load
references/websocket-hibernation.md
for complete handler patterns, hibernation lifecycle, serializeAttachment API, connection management, broadcasting patterns, and hibernation troubleshooting.

每个DO实例可处理数千个WebSocket连接,空闲约10秒后自动休眠,节省时长成本。连接在边缘保持开放,同时DO进入休眠状态。
关键规则
  • ✅ 使用
    ctx.acceptWebSocket(server)
    (启用休眠)
  • ✅ 使用
    ws.serializeAttachment(data)
    在休眠期间持久化元数据
  • ✅ 在构造函数中通过
    ctx.getWebSockets()
    恢复连接
  • ❌ 不要使用
    ws.accept()
    (标准API,无休眠功能)
  • ❌ 不要使用
    setTimeout
    /
    setInterval
    (阻止休眠)
处理方法
webSocketMessage()
webSocketClose()
webSocketError()
快速模式示例
typescript
export class ChatRoom extends DurableObject {
  sessions: Map<WebSocket, any>;

  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
    this.sessions = new Map();
    // 休眠后恢复连接
    ctx.getWebSockets().forEach(ws => {
      this.sessions.set(ws, ws.deserializeAttachment());
    });
  }

  async fetch(request: Request): Promise<Response> {
    const pair = new WebSocketPair();
    const [client, server] = Object.values(pair);

    this.ctx.acceptWebSocket(server);  // ← 启用休眠
    server.serializeAttachment({ userId: 'alice' });  // ← 休眠期间持久化
    this.sessions.set(server, { userId: 'alice' });

    return new Response(null, { status: 101, webSocket: client });
  }

  async webSocketMessage(ws: WebSocket, message: string): Promise<void> {
    const session = this.sessions.get(ws);
    // 广播至所有连接
    this.sessions.forEach((_, w) => w.send(message));
  }
}
加载
references/websocket-hibernation.md
获取完整的处理模式、休眠生命周期、serializeAttachment API、连接管理、广播模式及休眠故障排查方法。

Alarms API - Scheduled Tasks

告警API - 定时任务

Schedule DO to wake up at a future time for batching, cleanup, reminders, or periodic tasks.
Core API:
  • await ctx.storage.setAlarm(timestamp)
    - Schedule alarm
  • await ctx.storage.getAlarm()
    - Get current alarm time (null if not set)
  • await ctx.storage.deleteAlarm()
    - Cancel alarm
  • async alarm(info)
    - Handler called when alarm fires
Key Features:
  • ✅ Guaranteed at-least-once execution with automatic retries (up to 6)
  • ✅ Survives hibernation and eviction
  • ✅ Deleted automatically after successful execution
  • ⚠️ Only ONE alarm per DO (setting new one overwrites previous)
Quick pattern:
typescript
export class Batcher extends DurableObject {
  async addItem(item: string): Promise<void> {
    await this.ctx.storage.put('items', [...existingItems, item]);

    // Schedule batch processing if not already scheduled
    if (await this.ctx.storage.getAlarm() === null) {
      await this.ctx.storage.setAlarm(Date.now() + 10000);  // 10 seconds
    }
  }

  async alarm(info: { retryCount: number; isRetry: boolean }): Promise<void> {
    const items = await this.ctx.storage.get('items');
    await this.processBatch(items);  // Send to API, write to DB, etc.
    await this.ctx.storage.put('items', []);  // Clear buffer
  }
}
Load
references/alarms-api.md
for periodic alarms pattern, retry handling, error scenarios, cleanup jobs, and batching strategies.

调度DO在未来时间唤醒,用于批量处理、清理、提醒或周期性任务。
核心API
  • await ctx.storage.setAlarm(timestamp)
    - 调度告警
  • await ctx.storage.getAlarm()
    - 获取当前告警时间(未设置则返回null)
  • await ctx.storage.deleteAlarm()
    - 取消告警
  • async alarm(info)
    - 告警触发时调用的处理方法
核心特性
  • ✅ 保证至少执行一次,自动重试(最多6次)
  • ✅ 可在休眠与驱逐后存活
  • ✅ 执行成功后自动删除
  • ⚠️ 每个DO仅能设置一个告警(新告警会覆盖旧告警)
快速模式示例
typescript
export class Batcher extends DurableObject {
  async addItem(item: string): Promise<void> {
    await this.ctx.storage.put('items', [...existingItems, item]);

    // 若未调度则批量处理
    if (await this.ctx.storage.getAlarm() === null) {
      await this.ctx.storage.setAlarm(Date.now() + 10000);  // 10秒后
    }
  }

  async alarm(info: { retryCount: number; isRetry: boolean }): Promise<void> {
    const items = await this.ctx.storage.get('items');
    await this.processBatch(items);  // 发送至API、写入数据库等
    await this.ctx.storage.put('items', []);  // 清空缓冲区
  }
}
加载
references/alarms-api.md
获取周期性告警模式、重试处理、错误场景、清理任务及批量处理策略。

RPC vs HTTP Fetch

RPC与HTTP Fetch

RPC (Recommended): Call DO methods directly like
await stub.increment()
. Type-safe, simple, auto-serialization. Requires
compatibility_date >= 2024-04-03
.
HTTP Fetch: Traditional HTTP request/response with
async fetch(request)
handler. Required for WebSocket upgrades.
Quick comparison:
typescript
// RPC Pattern (simpler)
export class Counter extends DurableObject {
  async increment(): Promise<number> {  // ← Direct method
    let value = await this.ctx.storage.get<number>('count') || 0;
    return ++value;
  }
}
const count = await stub.increment();  // ← Direct call

// HTTP Fetch Pattern
export class Counter extends DurableObject {
  async fetch(request: Request): Promise<Response> {  // ← HTTP handler
    const url = new URL(request.url);
    if (url.pathname === '/increment') { /* ... */ }
  }
}
const response = await stub.fetch('/increment', { method: 'POST' });
Use RPC for: New projects, type safety, simple method calls Use HTTP Fetch for: WebSocket upgrades, complex routing, legacy code
Load
references/rpc-patterns.md
for complete RPC vs Fetch comparison, migration guide, error handling patterns, and method visibility control.

RPC(推荐):直接调用DO方法,如
await stub.increment()
,类型安全、简单易用、自动序列化。要求
compatibility_date >= 2024-04-03
HTTP Fetch:传统HTTP请求/响应模式,使用
async fetch(request)
处理方法,WebSocket升级需使用此方式。
快速对比
typescript
// RPC模式(更简洁)
export class Counter extends DurableObject {
  async increment(): Promise<number> {  // ← 直接方法
    let value = await this.ctx.storage.get<number>('count') || 0;
    return ++value;
  }
}
const count = await stub.increment();  // ← 直接调用

// HTTP Fetch模式
export class Counter extends DurableObject {
  async fetch(request: Request): Promise<Response> {  // ← HTTP处理方法
    const url = new URL(request.url);
    if (url.pathname === '/increment') { /* ... */ }
  }
}
const response = await stub.fetch('/increment', { method: 'POST' });
RPC适用场景:新项目、类型安全、简单方法调用 HTTP Fetch适用场景:WebSocket升级、复杂路由、遗留代码
加载
references/rpc-patterns.md
获取完整的RPC与Fetch对比、迁移指南、错误处理模式及方法可见性控制。

Creating Durable Object Stubs and Routing

创建Durable Object存根与路由

To interact with a Durable Object from a Worker: get an IDcreate a stubcall methods.
Three ID creation methods:
  1. idFromName(name)
    - Named DOs (most common): Deterministic routing to same instance globally
  2. newUniqueId()
    - Random IDs: New unique instance, must store ID for future access
  3. idFromString(idString)
    - Recreate from saved ID string
Getting stubs:
typescript
// Method 1: From ID
const id = env.CHAT_ROOM.idFromName('room-123');
const stub = env.CHAT_ROOM.get(id);

// Method 2: Shortcut for named DOs (recommended)
const stub = env.CHAT_ROOM.getByName('room-123');

await stub.myMethod();
Geographic routing with location hints:
  • Set
    locationHint
    option when creating stub:
    { locationHint: 'enam' }
  • 9 regions: wnam, enam, sam, weur, eeur, apac, oc, afr, me
  • Best-effort (not guaranteed), only affects first creation
Data residency with jurisdiction restrictions:
  • Use
    newUniqueId({ jurisdiction: 'eu' })
    or
    { jurisdiction: 'fedramp' }
  • Strictly enforced (DO never leaves jurisdiction)
  • Cannot combine with location hints
  • Required for GDPR/FedRAMP compliance
Load
references/stubs-routing.md
for complete guide to ID methods, stub management, location hints, jurisdiction restrictions, use cases, best practices, and error handling patterns.

要从Worker与Durable Object交互:获取ID创建存根调用方法
三种ID创建方式
  1. idFromName(name)
    - 命名DO(最常用):全局确定性路由至同一实例
  2. newUniqueId()
    - 随机ID:创建新的唯一实例,需存储ID以便后续访问
  3. idFromString(idString)
    - 从保存的ID字符串重建
获取存根
typescript
// 方式1:从ID创建
const id = env.CHAT_ROOM.idFromName('room-123');
const stub = env.CHAT_ROOM.get(id);

// 方式2:命名DO快捷方式(推荐)
const stub = env.CHAT_ROOM.getByName('room-123');

await stub.myMethod();
带位置提示的地理路由
  • 创建存根时设置
    locationHint
    选项:
    { locationHint: 'enam' }
  • 支持9个区域:wnam、enam、sam、weur、eeur、apac、oc、afr、me
  • 尽最大努力实现(不保证),仅影响首次创建
带管辖限制的数据驻留
  • 使用
    newUniqueId({ jurisdiction: 'eu' })
    { jurisdiction: 'fedramp' }
  • 严格执行(DO绝不会离开管辖区域)
  • 无法与位置提示组合使用
  • GDPR/FedRAMP合规要求
加载
references/stubs-routing.md
获取完整的ID方法指南、存根管理、位置提示、管辖限制、用例、最佳实践及错误处理模式。

Migrations - Managing DO Classes

迁移 - 管理DO类

Migrations are REQUIRED when creating, renaming, deleting, or transferring DO classes between Workers.
Four migration types:
  1. Create New DO: Use
    new_sqlite_classes
    (recommended, 1GB) or
    new_classes
    (legacy KV, 128MB)
  2. Rename DO: Use
    renamed_classes
    with
    from
    /
    to
    mapping (data preserved, bindings forward)
  3. Delete DO: Use
    deleted_classes
    (⚠️ immediate deletion, cannot undo, all storage lost)
  4. Transfer DO: Use
    transferred_classes
    with
    from_script
    (moves instances to new Worker)
Quick example - Create new DO with SQLite:
jsonc
{
  "durable_objects": {
    "bindings": [{ "name": "COUNTER", "class_name": "Counter" }]
  },
  "migrations": [
    {
      "tag": "v1",                    // Unique identifier (append-only)
      "new_sqlite_classes": ["Counter"]
    }
  ]
}
CRITICAL rules:
  • ❌ Migrations are ATOMIC (all instances migrate at once, no gradual rollout)
  • ❌ Cannot enable SQLite on existing KV-backed DOs (must create new class)
  • ❌ Migration tags must be unique (cannot reuse, append-only)
  • ✅ Code changes don't need migrations (only schema changes do)
  • ✅ DO class names are unique per account (across all Workers)
Load
references/migrations-guide.md
for complete migration patterns, rename/delete/transfer procedures, rollback strategies, and migration gotchas.

当创建、重命名、删除DO类或在Worker间转移DO类时,必须执行迁移
四种迁移类型
  1. 创建新DO:使用
    new_sqlite_classes
    (推荐,1GB)或
    new_classes
    (遗留KV,128MB)
  2. 重命名DO:使用
    renamed_classes
    并配置
    from
    /
    to
    映射(保留数据,绑定自动转发)
  3. 删除DO:使用
    deleted_classes
    (⚠️ 立即删除,无法撤销,所有存储数据丢失)
  4. 转移DO:使用
    transferred_classes
    并配置
    from_script
    (将实例转移至新Worker)
快速示例 - 使用SQLite创建新DO
jsonc
{
  "durable_objects": {
    "bindings": [{ "name": "COUNTER", "class_name": "Counter" }]
  },
  "migrations": [
    {
      "tag": "v1",                    // 唯一标识符(仅可追加)
      "new_sqlite_classes": ["Counter"]
    }
  ]
}
关键规则
  • ❌ 迁移是原子操作(所有实例同时迁移,无法渐进式发布)
  • ❌ 无法为现有KV-backed DO启用SQLite(必须创建新类)
  • ❌ 迁移标签必须唯一(不可重复使用,仅可追加)
  • ✅ 代码变更无需迁移(仅 schema变更需要)
  • ✅ DO类名称在账户内唯一(跨所有Worker)
加载
references/migrations-guide.md
获取完整的迁移模式、重命名/删除/转移流程、回滚策略及迁移注意事项。

Common Patterns

常见模式

Four production-ready patterns for Cloudflare Durable Objects:
  1. Rate Limiting - Per-user rate limiting with sliding window, KV storage for request tracking
  2. Session Management - User sessions with TTL, SQL storage, automatic cleanup via alarms
  3. Leader Election - Single leader guarantee using SQL constraints, heartbeat mechanism
  4. Multi-DO Coordination - Game coordinator + game rooms pattern, parent-child DO relationships
Quick example - Rate limiter:
typescript
export class RateLimiter extends DurableObject {
  async checkLimit(userId: string, limit: number, window: number): Promise<boolean> {
    const requests = await this.ctx.storage.get<number[]>(`rate:${userId}`) || [];
    const validRequests = requests.filter(t => Date.now() - t < window);

    if (validRequests.length >= limit) return false;

    validRequests.push(Date.now());
    await this.ctx.storage.put(`rate:${userId}`, validRequests);
    return true;
  }
}
Load
references/common-patterns.md
for complete implementations of all 4 patterns with full code examples, SQL schemas, alarm usage, error handling, and best practices.

Cloudflare Durable Objects的四种生产就绪模式
  1. 限流 - 基于用户的滑动窗口限流,使用KV存储跟踪请求
  2. 会话管理 - 带TTL的用户会话,使用SQL存储,通过告警自动清理
  3. 主节点选举 - 使用SQL约束保证单主节点,心跳机制
  4. 多DO协调 - 游戏协调器+游戏房间模式,父子DO关系
快速示例 - 限流器
typescript
export class RateLimiter extends DurableObject {
  async checkLimit(userId: string, limit: number, window: number): Promise<boolean> {
    const requests = await this.ctx.storage.get<number[]>(`rate:${userId}`) || [];
    const validRequests = requests.filter(t => Date.now() - t < window);

    if (validRequests.length >= limit) return false;

    validRequests.push(Date.now());
    await this.ctx.storage.put(`rate:${userId}`, validRequests);
    return true;
  }
}
加载
references/common-patterns.md
获取所有4种模式的完整实现,包括代码示例、SQL schema、告警使用、错误处理及最佳实践。

Critical Rules

关键规则

✅ Always:
  • Export DO class:
    export default MyDO
  • Call
    super(ctx, env)
    first in constructor
  • Use
    new_sqlite_classes
    in migrations (1GB vs 128MB KV)
  • Use
    ctx.acceptWebSocket()
    for hibernation (not
    ws.accept()
    )
  • Persist state to storage (not just memory)
  • Use alarms instead of setTimeout/setInterval
  • Use parameterized SQL:
    sql.exec('... WHERE id = ?', id)
  • Minimize constructor work, use
    blockConcurrencyWhile()
❌ Never:
  • Create DO without migration (error)
  • Forget to export class (binding not found)
  • Use setTimeout/setInterval (prevents hibernation)
  • Rely only on in-memory state for WebSockets (use serializeAttachment)
  • Deploy migrations gradually (migrations are atomic)
  • Enable SQLite on existing KV-backed DO (must create new class)
  • Assume location hints are guaranteed (best-effort only)

✅ 必须遵守
  • 导出DO类:
    export default MyDO
  • 构造函数中第一行调用
    super(ctx, env)
  • 迁移中使用
    new_sqlite_classes
    (1GB对比128MB KV)
  • 使用
    ctx.acceptWebSocket()
    实现休眠(而非
    ws.accept()
  • 将状态持久化至存储(而非仅保存在内存)
  • 使用告警替代setTimeout/setInterval
  • 使用参数化SQL:
    sql.exec('... WHERE id = ?', id)
  • 最小化构造函数工作量,使用
    blockConcurrencyWhile()
❌ 绝对禁止
  • 不执行迁移就创建DO(会报错)
  • 忘记导出类(绑定未找到)
  • 使用setTimeout/setInterval(阻止休眠)
  • WebSocket仅依赖内存状态(使用serializeAttachment)
  • 渐进式部署迁移(迁移是原子操作)
  • 为现有KV-backed DO启用SQLite(必须创建新类)
  • 假设位置提示一定会生效(仅尽最大努力)

Known Issues Prevention

已知问题预防

This skill prevents 15+ documented issues. Top 3 most critical:
本技能可预防15+种已记录的问题。最关键的3个问题:

Issue #1: Class Not Exported

问题1:类未导出

Error:
"binding not found"
| Why: DO class not exported Fix:
export default MyDO;
错误
"binding not found"
| 原因:DO类未导出 修复:添加
export default MyDO;

Issue #2: Missing Migration

问题2:缺少迁移

Error:
"migrations required"
| Why: Created DO without migration entry Fix: Add
{ "tag": "v1", "new_sqlite_classes": ["MyDO"] }
to migrations
错误
"migrations required"
| 原因:创建DO但未添加迁移条目 修复:在migrations中添加
{ "tag": "v1", "new_sqlite_classes": ["MyDO"] }

Issue #3: setTimeout Breaks Hibernation

问题3:setTimeout破坏休眠

Error: DO never hibernates, high charges | Why:
setTimeout
prevents hibernation Fix: Use
await ctx.storage.setAlarm(Date.now() + 1000)
instead
12 more issues covered: Wrong migration type, constructor overhead, in-memory state lost, outgoing WebSocket no hibernation, global uniqueness confusion, partial deleteAll, binding mismatch, state size exceeded, migration not atomic, location hint ignored, alarm retry failures, fetch blocks hibernation.
Load
references/top-errors.md
for complete error catalog with all 15+ issues, detailed prevention strategies, debugging steps, and resolution patterns.

错误:DO永不休眠,费用过高 | 原因
setTimeout
阻止休眠 修复:使用
await ctx.storage.setAlarm(Date.now() + 1000)
替代
还涵盖12个其他问题:错误的迁移类型、构造函数过载、内存状态丢失、出站WebSocket无休眠、全局唯一性混淆、partial deleteAll、绑定不匹配、状态大小超限、迁移非原子、位置提示被忽略、告警重试失败、fetch阻止休眠。
加载
references/top-errors.md
获取完整的错误目录,包含所有15+种问题、详细预防策略、调试步骤及解决模式。

Configuration & TypeScript

配置与TypeScript

Configure wrangler.jsonc with DO bindings and migrations, set up TypeScript types with proper exports.
Load
references/typescript-config.md
for
: wrangler.jsonc structure, TypeScript types, Env interface, tsconfig.json, common type issues

在wrangler.jsonc中配置DO绑定与迁移,设置TypeScript类型并正确导出。
加载
references/typescript-config.md
获取
:wrangler.jsonc结构、TypeScript类型、Env接口、tsconfig.json、常见类型问题