Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive Cloudflare platform skill covering Workers, D1, R2, KV, AI, Durable Objects, and security.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/durable-objects/api.md
1# Durable Objects API23## Class Structure45```typescript6import { DurableObject } from "cloudflare:workers";78export class MyDO extends DurableObject<Env> {9constructor(ctx: DurableObjectState, env: Env) {10super(ctx, env);11// Runs on EVERY wake - keep light!12}1314// RPC methods (called directly from worker)15async myMethod(arg: string): Promise<string> { return arg; }1617// fetch handler (legacy/HTTP semantics)18async fetch(req: Request): Promise<Response> { /* ... */ }1920// Lifecycle handlers21async alarm() { /* alarm fired */ }22async webSocketMessage(ws: WebSocket, msg: string | ArrayBuffer) { /* ... */ }23async webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean) { /* ... */ }24async webSocketError(ws: WebSocket, error: unknown) { /* ... */ }25}26```2728## DurableObjectState Context Methods2930### Concurrency Control3132```typescript33// Complete work after response sent (e.g., cleanup, logging)34this.ctx.waitUntil(promise: Promise<any>): void3536// Critical section - blocks all other requests until complete37await this.ctx.blockConcurrencyWhile(async () => {38// No other requests processed during this block39// Use for initialization or critical operations40})41```4243**When to use:**44- `waitUntil()`: Background cleanup, logging, non-critical work after response45- `blockConcurrencyWhile()`: First-time init, schema migration, critical state setup4647### Lifecycle4849```typescript50this.ctx.id // DurableObjectId of this instance51this.ctx.abort() // Force eviction (use after PITR restore to reload state)52```5354### Storage Access5556```typescript57this.ctx.storage.sql // SQLite API (recommended)58this.ctx.storage.kv // Sync KV API (SQLite DOs only)59this.ctx.storage // Async KV API (legacy/KV-only DOs)60```6162See **[DO Storage](../do-storage/README.md)** for complete storage API reference.6364### WebSocket Management6566```typescript67this.ctx.acceptWebSocket(ws: WebSocket, tags?: string[]) // Enable hibernation68this.ctx.getWebSockets(tag?: string): WebSocket[] // Get by tag or all69this.ctx.getTags(ws: WebSocket): string[] // Get tags for connection70```7172### Alarms7374```typescript75await this.ctx.storage.setAlarm(timestamp: number | Date) // Schedule (overwrites existing)76await this.ctx.storage.getAlarm(): number | null // Get next alarm time77await this.ctx.storage.deleteAlarm(): void // Cancel alarm78```7980**Limit:** 1 alarm per DO. Use queue pattern for multiple events (see [Patterns](./patterns.md)).8182## Storage APIs8384For detailed storage documentation including SQLite queries, KV operations, transactions, and Point-in-Time Recovery, see **[DO Storage](../do-storage/README.md)**.8586Quick reference:8788```typescript89// SQLite (recommended)90this.ctx.storage.sql.exec("SELECT * FROM users WHERE id = ?", userId).one()9192// Sync KV (SQLite DOs only)93this.ctx.storage.kv.get("key")9495// Async KV (legacy)96await this.ctx.storage.get("key")97```9899## Alarms100101Schedule future work that survives eviction:102103```typescript104// Set alarm (overwrites any existing alarm)105await this.ctx.storage.setAlarm(Date.now() + 3600000) // 1 hour from now106await this.ctx.storage.setAlarm(new Date("2026-02-01")) // Absolute time107108// Check next alarm109const nextRun = await this.ctx.storage.getAlarm() // null if none110111// Cancel alarm112await this.ctx.storage.deleteAlarm()113114// Handler called when alarm fires115async alarm() {116// Runs once alarm triggers117// DO wakes from hibernation if needed118// Use for cleanup, notifications, scheduled tasks119}120```121122**Limitations:**123- 1 alarm per DO maximum124- Overwrites previous alarm when set125- Use queue pattern for multiple scheduled events (see [Patterns](./patterns.md))126127**Reliability:**128- Alarms survive DO eviction/restart129- Cloudflare retries failed alarms automatically130- Not guaranteed exactly-once (handle idempotently)131132## WebSocket Hibernation133134Hibernation allows DOs with open WebSocket connections to consume zero compute/memory until message arrives.135136```typescript137async fetch(req: Request): Promise<Response> {138const [client, server] = Object.values(new WebSocketPair());139this.ctx.acceptWebSocket(server, ["room:123"]); // Tags for filtering140server.serializeAttachment({ userId: "abc" }); // Persisted metadata141return new Response(null, { status: 101, webSocket: client });142}143144// Called when message arrives (DO wakes from hibernation)145async webSocketMessage(ws: WebSocket, msg: string | ArrayBuffer) {146const data = ws.deserializeAttachment(); // Retrieve metadata147for (const c of this.ctx.getWebSockets("room:123")) c.send(msg);148}149150// Called on close (optional handler)151async webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean) {152// Cleanup logic, remove from lists, etc.153}154155// Called on error (optional handler)156async webSocketError(ws: WebSocket, error: unknown) {157console.error("WebSocket error:", error);158// Handle error, close connection, etc.159}160```161162**Key concepts:**163- **Auto-hibernation:** DO hibernates when no active requests/alarms164- **Zero cost:** Hibernated DOs incur no charges while preserving connections165- **Memory cleared:** All in-memory state lost on hibernation166- **Attachment persistence:** Use `serializeAttachment()` for per-connection metadata that survives hibernation167- **Tags for filtering:** Group connections by room/channel/user for targeted broadcasts168169**Handler lifecycle:**170- `webSocketMessage`: DO wakes, processes message, may hibernate after171- `webSocketClose`: Called when client closes (optional - implement for cleanup)172- `webSocketError`: Called on connection error (optional - implement for error handling)173174**Metadata persistence:**175```typescript176// Store connection metadata (survives hibernation)177ws.serializeAttachment({ userId: "abc", room: "lobby" })178179// Retrieve after hibernation180const { userId, room } = ws.deserializeAttachment()181```182183## See Also184185- **[DO Storage](../do-storage/README.md)** - Complete storage API reference186- **[Patterns](./patterns.md)** - Real-world usage patterns187- **[Gotchas](./gotchas.md)** - Hibernation caveats and limits188