Build real-time & multiplayer apps without a degree in distributed systems.
Ship multiplayer systems, chat services, session stores and other coordination-heavy apps using Durable Objects.
Stateful serverless
WebSockets included
Like a micro-VM
Embedded SQL database
Schedule Work
@cloudflare/actors
Durable Objects The building block for real-time apps
Power chat rooms, multiplayer sessions, collaborative docs, and live dashboards. Durable Objects run close to users, maintain consistent state, and broadcast updates instantly – no Redis clusters or orchestration required.
Build chat systems and messaging apps
Create collaborative editing experiences
Power multiplayer games and interactive experiences
Coordinate live dashboards and real-time analytics
The simplest way to build real-time systems at global scale
Durable Objects give every developer the building blocks for coordination, state, and real-time communication—without managing Redis, clusters, or distributed locks. Used by teams shipping multiplayer apps, live dashboards, and collaborative editors that just work.
import { DurableObject } from 'cloudflare:workers';
export default { async fetch(request, env) { const url = new URL(request.url); const counterName = url.searchParams.get('name'); if (!counterName) return new Response('missing ?name', { status: 400 });
const counterStub = env.COUNTERS.getByName(counterName);
let count; switch (url.pathname) { case '/increment': count = await counterStub.increment(); break; case '/decrement': count = await counterStub.decrement(); break; case '/': count = await counterStub.get(); break; default: return new Response('not found', { status: 404 }); } return new Response(`${count}`); },};
export class Counter extends DurableObject { async get() { return (await this.ctx.storage.get('value')) ?? 0; } async increment(amount = 1) { const newValue = (await this.get()) + amount; await this.ctx.storage.put('value', newValue); return newValue; } async decrement(amount = 1) { const newValue = (await this.get()) - amount; await this.ctx.storage.put('value', newValue); return newValue; }}import { DurableObject } from 'cloudflare:workers';
export class WebSocketServer extends DurableObject { async fetch() { const webSocketPair = new WebSocketPair(); const [client, server] = Object.values(webSocketPair); this.ctx.acceptWebSocket(server);
return new Response(null, { status: 101, webSocket: client, }); }
async webSocketMessage(ws, message) { ws.send( `[Durable Object] message: ${message}, connections: ${this.ctx.getWebSockets().length}`, ); }}