Cloudflare Durable Objects Developer

Durable objects

by cloudflare · Apache-2.0 license · ★ 2,976 on GitHub

Durable objects cover

Build, debug, or review Cloudflare Durable Objects code for persistent state and coordination.

---
name: durable-objects
description: Build, debug, or review Cloudflare Durable Objects code for persistent state and coordination.
---

# Durable Objects

Build stateful, coordinated applications on Cloudflare's edge using Durable Objects.

## Retrieval Sources

Your knowledge of Durable Objects APIs and configuration may be outdated. **Prefer retrieval over pre-training** for any Durable Objects task.

| Resource | URL |
|----------|-----|
| Docs | https://developers.cloudflare.com/durable-objects/index.md |
| API Reference | https://developers.cloudflare.com/durable-objects/api/index.md |
| Best Practices | https://developers.cloudflare.com/durable-objects/best-practices/index.md |

Overview

Build stateful, coordinated applications on Cloudflare's edge using Durable Objects.

Manual install (npx, ZIP)
Claude Codenpx skills add cloudflare/skills --skill durable-objects -g -a claude-code
Claude Code (degit)npx degit cloudflare/skills/skills/durable-objects#main ~/.claude/skills/durable-objects
Claude.ai / desktopZip the folder and upload it under Settings → Capabilities → Skills.
Codex, Cursor, other agentsPoint them at SKILL.md. The other files are plain text.

Connects with Agent Alley MCP · agentalley.io/mcp

Files included

  • SKILL.md5.9 KB
Read SKILL.md here
cloudflare/main1 file shown
SKILL.md
Show the full text181 lines

Durable Objects

Build stateful, coordinated applications on Cloudflare's edge using Durable Objects.

Retrieval Sources

Your knowledge of Durable Objects APIs and configuration may be outdated. Prefer retrieval over pre-training for any Durable Objects task.

Resource URL
Docs https://developers.cloudflare.com/durable-objects/index.md
API Reference https://developers.cloudflare.com/durable-objects/api/index.md
Best Practices https://developers.cloudflare.com/durable-objects/best-practices/index.md
Examples https://developers.cloudflare.com/durable-objects/examples/index.md
Roles and permissions https://developers.cloudflare.com/workers/authorization/durable-objects/index.md

Fetch the relevant doc page when implementing features.

When to Use

  • Creating new Durable Object classes for stateful coordination
  • Implementing RPC methods, alarms, or WebSocket handlers
  • Reviewing existing DO code for best practices
  • Configuring wrangler.jsonc/toml for DO bindings and migrations
  • Writing tests with Cloudflare’s Vitest integration
  • Designing sharding strategies and parent-child relationships

Reference Documentation

  • ./references/rules.md - Core rules, storage, concurrency, RPC, alarms
  • Testing reference - Current Vitest documentation, migration choices, and test selection
  • ./references/workers.md - Workers handlers, types, wrangler config, observability

Search: blockConcurrencyWhile, idFromName, getByName, setAlarm, sql.exec

Core Principles

Use Durable Objects For
Need Example
Coordination Chat rooms, multiplayer games, collaborative docs
Strong consistency Inventory, booking systems, turn-based games
Per-entity storage Multi-tenant SaaS, per-user data
Persistent connections WebSockets, real-time notifications
Scheduled work per entity Subscription renewals, game timeouts
Do NOT Use For
  • Stateless request handling (use plain Workers)
  • Maximum global distribution needs
  • High fan-out independent requests

Quick Reference

Wrangler Configuration
// wrangler.jsonc
{
  "durable_objects": {
    "bindings": [{ "name": "MY_DO", "class_name": "MyDurableObject" }]
  },
  "migrations": [{ "tag": "v1", "new_sqlite_classes": ["MyDurableObject"] }]
}
Basic Durable Object Pattern
import { DurableObject } from "cloudflare:workers";

export interface Env {
  MY_DO: DurableObjectNamespace<MyDurableObject>;
}

export class MyDurableObject extends DurableObject<Env> {
  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
    ctx.blockConcurrencyWhile(async () => {
      this.ctx.storage.sql.exec(`
        CREATE TABLE IF NOT EXISTS items (
          id INTEGER PRIMARY KEY AUTOINCREMENT,
          data TEXT NOT NULL
        )
      `);
    });
  }

  async addItem(data: string): Promise<number> {
    const result = this.ctx.storage.sql.exec<{ id: number }>(
      "INSERT INTO items (data) VALUES (?) RETURNING id",
      data
    );
    return result.one().id;
  }
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const stub = env.MY_DO.getByName("my-instance");
    const id = await stub.addItem("hello");
    return Response.json({ id });
  },
};

Critical Rules

  1. Model around coordination atoms - One DO per chat room/game/user, not one global DO
  2. Use getByName() for deterministic routing - Same input = same DO instance
  3. Use SQLite storage - Configure new_sqlite_classes in migrations
  4. Initialize in constructor - Use blockConcurrencyWhile() for schema setup only
  5. Use RPC methods - Not fetch() handler (compatibility date >= 2024-04-03)
  6. Persist first, cache second - Always write to storage before updating in-memory state
  7. One alarm per DO - setAlarm() replaces any existing alarm

Authorization

Durable Objects do not have separate roles or permissions; access follows the Worker that implements them. Retrieve the current Durable Objects authorization guidance before granting observability or Data Studio access, and scope the Workers role to the intended Worker or Workers product.

Anti-Patterns (NEVER)

  • Single global DO handling all requests (bottleneck)
  • Using blockConcurrencyWhile() on every request (kills throughput)
  • Storing critical state only in memory (lost on eviction/crash)
  • Using await between related storage writes (breaks atomicity)
  • Holding blockConcurrencyWhile() across fetch() or external I/O

Stub Creation

// Deterministic - preferred for most cases
const stub = env.MY_DO.getByName("room-123");

// From existing ID string
const id = env.MY_DO.idFromString(storedIdString);
const stub = env.MY_DO.get(id);

// New unique ID - store mapping externally
const id = env.MY_DO.newUniqueId();
const stub = env.MY_DO.get(id);

Storage Operations

// SQL (synchronous, recommended)
this.ctx.storage.sql.exec("INSERT INTO t (c) VALUES (?)", value);
const rows = this.ctx.storage.sql.exec<Row>("SELECT * FROM t").toArray();

// KV (async)
await this.ctx.storage.put("key", value);
const val = await this.ctx.storage.get<Type>("key");

Alarms

// Schedule (replaces existing)
await this.ctx.storage.setAlarm(Date.now() + 60_000);

// Handler
async alarm(): Promise<void> {
  // Process scheduled work
  // Optionally reschedule: await this.ctx.storage.setAlarm(...)
}

// Cancel
await this.ctx.storage.deleteAlarm();

Testing

Read the testing reference before configuring a suite or writing Durable Object tests. It routes to current setup, APIs, and examples and identifies the behavior to cover.

1---
2name: durable-objects
3description: Build, debug, or review Cloudflare Durable Objects code for persistent state and coordination.
4---
5 
6# Durable Objects
7 
8Build stateful, coordinated applications on Cloudflare's edge using Durable Objects.
9 
10## Retrieval Sources
11 
12Your knowledge of Durable Objects APIs and configuration may be outdated. **Prefer retrieval over pre-training** for any Durable Objects task.
13 
14| Resource | URL |
15|----------|-----|
16| Docs | https://developers.cloudflare.com/durable-objects/index.md |
17| API Reference | https://developers.cloudflare.com/durable-objects/api/index.md |
18| Best Practices | https://developers.cloudflare.com/durable-objects/best-practices/index.md |
19| Examples | https://developers.cloudflare.com/durable-objects/examples/index.md |
20| Roles and permissions | https://developers.cloudflare.com/workers/authorization/durable-objects/index.md |
21 
22Fetch the relevant doc page when implementing features.
23 
24## When to Use
25 
26- Creating new Durable Object classes for stateful coordination
27- Implementing RPC methods, alarms, or WebSocket handlers
28- Reviewing existing DO code for best practices
29- Configuring wrangler.jsonc/toml for DO bindings and migrations
30- Writing tests with Cloudflare’s Vitest integration
31- Designing sharding strategies and parent-child relationships
32 
33## Reference Documentation
34 
35- `./references/rules.md` - Core rules, storage, concurrency, RPC, alarms
36- [Testing reference](./references/testing.md) - Current Vitest documentation, migration choices, and test selection
37- `./references/workers.md` - Workers handlers, types, wrangler config, observability
38 
39Search: `blockConcurrencyWhile`, `idFromName`, `getByName`, `setAlarm`, `sql.exec`
40 
41## Core Principles
42 
43### Use Durable Objects For
44 
45| Need | Example |
46|------|---------|
47| Coordination | Chat rooms, multiplayer games, collaborative docs |
48| Strong consistency | Inventory, booking systems, turn-based games |
49| Per-entity storage | Multi-tenant SaaS, per-user data |
50| Persistent connections | WebSockets, real-time notifications |
51| Scheduled work per entity | Subscription renewals, game timeouts |
52 
53### Do NOT Use For
54 
55- Stateless request handling (use plain Workers)
56- Maximum global distribution needs
57- High fan-out independent requests
58 
59## Quick Reference
60 
61### Wrangler Configuration
62 
63```jsonc
64// wrangler.jsonc
65{
66 "durable_objects": {
67 "bindings": [{ "name": "MY_DO", "class_name": "MyDurableObject" }]
68 },
69 "migrations": [{ "tag": "v1", "new_sqlite_classes": ["MyDurableObject"] }]
70}
71```
72 
73### Basic Durable Object Pattern
74 
75```typescript
76import { DurableObject } from "cloudflare:workers";
77 
78export interface Env {
79 MY_DO: DurableObjectNamespace<MyDurableObject>;
80}
81 
82export class MyDurableObject extends DurableObject<Env> {
83 constructor(ctx: DurableObjectState, env: Env) {
84 super(ctx, env);
85 ctx.blockConcurrencyWhile(async () => {
86 this.ctx.storage.sql.exec(`
87 CREATE TABLE IF NOT EXISTS items (
88 id INTEGER PRIMARY KEY AUTOINCREMENT,
89 data TEXT NOT NULL
90 )
91 `);
92 });
93 }
94 
95 async addItem(data: string): Promise<number> {
96 const result = this.ctx.storage.sql.exec<{ id: number }>(
97 "INSERT INTO items (data) VALUES (?) RETURNING id",
98 data
99 );
100 return result.one().id;
101 }
102}
103 
104export default {
105 async fetch(request: Request, env: Env): Promise<Response> {
106 const stub = env.MY_DO.getByName("my-instance");
107 const id = await stub.addItem("hello");
108 return Response.json({ id });
109 },
110};
111```
112 
113## Critical Rules
114 
1151. **Model around coordination atoms** - One DO per chat room/game/user, not one global DO
1162. **Use `getByName()` for deterministic routing** - Same input = same DO instance
1173. **Use SQLite storage** - Configure `new_sqlite_classes` in migrations
1184. **Initialize in constructor** - Use `blockConcurrencyWhile()` for schema setup only
1195. **Use RPC methods** - Not fetch() handler (compatibility date >= 2024-04-03)
1206. **Persist first, cache second** - Always write to storage before updating in-memory state
1217. **One alarm per DO** - `setAlarm()` replaces any existing alarm
122 
123## Authorization
124 
125Durable Objects do not have separate roles or permissions; access follows the Worker that implements them. Retrieve the current [Durable Objects authorization guidance](https://developers.cloudflare.com/workers/authorization/durable-objects/index.md) before granting observability or Data Studio access, and scope the Workers role to the intended Worker or Workers product.
126 
127## Anti-Patterns (NEVER)
128 
129- Single global DO handling all requests (bottleneck)
130- Using `blockConcurrencyWhile()` on every request (kills throughput)
131- Storing critical state only in memory (lost on eviction/crash)
132- Using `await` between related storage writes (breaks atomicity)
133- Holding `blockConcurrencyWhile()` across `fetch()` or external I/O
134 
135## Stub Creation
136 
137```typescript
138// Deterministic - preferred for most cases
139const stub = env.MY_DO.getByName("room-123");
140 
141// From existing ID string
142const id = env.MY_DO.idFromString(storedIdString);
143const stub = env.MY_DO.get(id);
144 
145// New unique ID - store mapping externally
146const id = env.MY_DO.newUniqueId();
147const stub = env.MY_DO.get(id);
148```
149 
150## Storage Operations
151 
152```typescript
153// SQL (synchronous, recommended)
154this.ctx.storage.sql.exec("INSERT INTO t (c) VALUES (?)", value);
155const rows = this.ctx.storage.sql.exec<Row>("SELECT * FROM t").toArray();
156 
157// KV (async)
158await this.ctx.storage.put("key", value);
159const val = await this.ctx.storage.get<Type>("key");
160```
161 
162## Alarms
163 
164```typescript
165// Schedule (replaces existing)
166await this.ctx.storage.setAlarm(Date.now() + 60_000);
167 
168// Handler
169async alarm(): Promise<void> {
170 // Process scheduled work
171 // Optionally reschedule: await this.ctx.storage.setAlarm(...)
172}
173 
174// Cancel
175await this.ctx.storage.deleteAlarm();
176```
177 
178## Testing
179 
180Read the [testing reference](./references/testing.md) before configuring a suite or writing Durable Object tests. It routes to current setup, APIs, and examples and identifies the behavior to cover.
181 
View all files on GitHub →

Details

License
Apache-2.0
Stars on the repo
★ 2,976
Checked
Source
cloudflare/skills ↗
Creator
cloudflare · 17 listings
View creator

Similar skills

See all →

More from cloudflare

SkillSecurity Audit Reviewercloudflare/security-audit-skill · by cloudflareSecurity guidance and vulnerability review for codebases, APIs, services, CLI tools, libraries, and daemons. Use for security questions, focused reviews, vulnerability research, security audits, or pen tests. Run the complete workflow only for explicit codebase audit or pen-test requests, full/comprehensive/end-to-end reviews, or requested report artifacts.★ 26.1k GitHub starsAgentCloudflare MCP Hubcloudflare/mcp-server-cloudflare · by cloudflareCloudflare's hosted servers for Workers, docs, observability, logs and browser rendering.★ 4.3k GitHub starsSkillCloudflare Agents SDK Buildercloudflare/skills · by cloudflareBuild, debug, or review Cloudflare Agents SDK applications using the agents package.★ 3k GitHub starsSkillBasin Analytics Workflowcloudflare/skills · by cloudflareBuild and troubleshoot Cloudflare Basin analytics workflows with Basin Pipelines, Basin Catalog, and Basin SQL. Use for streaming data into R2 Iceberg tables, managing catalogs, or querying those tables; also use for requests using the former Data Platform, Pipelines, R2 Data Catalog, or R2 SQL names.★ 3k GitHub starsSkillCloudflare Email Configcloudflare/skills · by cloudflareImplement or troubleshoot Cloudflare Email Sending and Email Routing integrations and their delivery configuration.★ 3k GitHub starsSkillCloudflare K2 Stream Buildercloudflare/skills · by cloudflareBuild and troubleshoot Cloudflare K2 or K2 Streams durable logs. Use for stream setup, producing from Workers or HTTP, configuring retention and inputs, and consuming through subscriptions.★ 3k GitHub stars