Durable Objects
A single, always-there object that combines code with its own storage — perfect for live chat, multiplayer, and anything where everyone must agree on one source of truth.
What are Durable Objects?
A Durable Object is a special kind of Worker that uniquely combines compute (running code) with its own private storage. For any given name there is exactly one instance, living in one place, that everyone in the world talks to.
"Stateful" means it remembers things between requests. A normal Worker forgets everything the moment it finishes — it's "stateless." A Durable Object keeps its data (in memory and in durable storage), so the next request sees what the last one left behind.
Think of it like…
Imagine one dedicated receptionist for each meeting room. Everyone who wants that room always goes to that exact same person, who keeps the room's schedule in their own notebook. No double-bookings, no confusion — one room, one keeper of the truth.
Why use it?
Coordinating many users in real time is one of the hardest problems in software. Normally you need databases, locks, and message brokers to stop people from overwriting each other. Durable Objects make it simple: because there's only one instance per name, it naturally becomes the single point of coordination.
Single source of truth
One instance per name means no conflicting copies and no race conditions to untangle.
Built-in storage
Each object has its own SQLite database — strongly consistent and fast, with no separate database to wire up.
Real-time coordination
Hold WebSocket connections open and broadcast updates to many clients at once.
No cold starts
Like Workers, they spin up instantly and run at the edge near your users.
Scale by count
Create unlimited objects — one per chat room, document, or user — and they scale horizontally.
Alarms
Schedule an object to wake itself up later to run work — no external cron needed.
When should you use it?
Reach for Durable Objects whenever multiple people or requests need to share and agree on the same live state.
Live chat rooms
One object per room holds every connection and broadcasts each new message instantly.
Collaborative editing
Google-Docs-style apps where many people edit one document at the same time.
Multiplayer games
One object per game session keeps the authoritative game state for all players.
Carts & counters
A per-user cart or a per-resource counter that must never lose or double-count.
Rate limiting
Track how often a user hits an API and enforce limits from one consistent place.
AI agents
Give each AI agent its own long-lived memory and state that persists across turns.
How do you get started?
You write a Durable Object as a JavaScript/TypeScript class, register it in wrangler.jsonc with a binding and a migration, then call it from a normal Worker by looking it up by name.
Create a Worker project
Start from the Hello World template, then add your Durable Object class to the code.
npm create cloudflare@latest -- my-do-app cd my-do-appRegister the object
In wrangler.jsonc, add a binding (the name your Worker uses) and a migration (which tells Cloudflare this is a new SQLite-backed class).
{ "durable_objects": { "bindings": [ { "name": "MY_DURABLE_OBJECT", "class_name": "MyDurableObject" } ] }, "migrations": [ { "tag": "v1", "new_sqlite_classes": ["MyDurableObject"] } ] }Deploy
Publish to Cloudflare's network. Each unique name you request will get its own instance automatically.
npx wrangler deploy
import { DurableObject } from "cloudflare:workers";
export class MyDurableObject extends DurableObject {
// Run a query against this object's own private SQLite database
async sayHello() {
const row = this.ctx.storage.sql
.exec("SELECT 'Hello, World!' AS greeting")
.one();
return row.greeting;
}
}
export default {
async fetch(request, env) {
// getByName returns the ONE instance for this name (creating it if needed)
const stub = env.MY_DURABLE_OBJECT.getByName("room-42");
// Call a method on it directly via RPC
const greeting = await stub.sayHello();
return new Response(greeting);
},
};Names map to instances
getByName("room-42") always returns the same single instance. Use "room-42" again from anywhere on Earth and you reach the exact same object with the same memory and storage. That is the whole magic.
Key concepts
ID / name
A globally unique identifier that maps to exactly one instance. Same name = same object.
Stub
A local handle you call methods on; Cloudflare routes the call to the real object wherever it lives.
Storage API
Transactional, strongly consistent SQLite storage built right into each object.
WebSocket Hibernation
Keep thousands of connections open cheaply — the object sleeps but its connections stay alive.
Alarms
Schedule the object to wake itself at a future time to do work, like retries or cleanup.
Migration
A small config entry that tells Cloudflare you're adding, renaming, or removing an object class.
Tips & pricing
Free to try
SQLite-backed Durable Objects are available on the Workers Free plan (with lower limits), so you can build a real-time app and learn the model without paying.
Good limits to remember
- Number of objects: unlimited per account / per class
- Storage per object: up to 10 GB of SQLite on the Paid plan
- Throughput: a soft limit of ~1,000 requests/second per object
- CPU time: 30s default, configurable up to 5 minutes
- SQLite key + value combined: up to 2 MB
One object = one bottleneck
Because all traffic for a name funnels through a single instance, a hugely popular object can become a bottleneck (~1,000 req/s). Split work across many objects — e.g. one per room or user — to scale.
Related products
menu_bookOfficial docsopen_in_new