Durable Objects
What it is
Think of a single front-desk clerk who handles one person at a time and remembers everyone who came before — no second clerk can give a conflicting answer. A Durable Object is that clerk in software: a tiny server that keeps its own memory (it is "stateful") and that Cloudflare guarantees exists in exactly one place at a time. Each object has a unique ID, its own permanent storage, and processes requests one at a time, so it's a natural home for coordination — counters, locks, game rooms, chat sessions. Where a Worker forgets everything between requests (it is "stateless") and runs everywhere at once, a Durable Object remembers and is singular.
Strengths
- Single-instance guarantee — no race conditions across replicas.
- Built-in persistent storage (now backed by SQLite) co-located with the object.
- Ideal for real-time apps: WebSockets (a live, two-way connection that stays open so the server can push updates instantly), presence, live collaboration.
- Strong consistency: read-after-write within an object is immediate.
- Alarms let an object schedule its own future work.
Trade-offs
- Single-threaded per object — a hot object can become a bottleneck; shard by key.
- More to reason about than a plain Worker; you design the object boundaries.
- Storage per object is bounded; not a substitute for D1 (a ) or R2 (file storage) at scale.
- Overkill for stateless request handling.
When to use it
Reach for Durable Objects when you need coordination or per-entity state: chat rooms, multiplayer game state, rate limiters, leader election, or a live document that many clients edit at once.
Vibe coding fit
Durable Objects shine for the real-time features that are otherwise fiddly to build, and an can scaffold the class, the binding, and the WebSocket handling. Tell it how to shard — usually one object per room, user, or document — so a single object doesn't serialize all your traffic. The config below declares a Durable Object class with a migration.
# wrangler.toml
[[durable_objects.bindings]]
name = "ROOM"
class_name = "ChatRoom"
[[migrations]]
tag = "v1"
new_sqlite_classes = ["ChatRoom"]
npx wrangler deploy