Use WebSockets
Durable Objects can act as WebSocket servers that connect thousands of clients per instance. You can also use WebSockets as a client to connect to other servers or Durable Objects.
Two WebSocket APIs are available:
- Hibernation WebSocket API - Allows the Durable Object to hibernate without disconnecting clients when idle. (recommended)
- Web Standard WebSocket API - Uses the familiar
addEventListenerevent pattern.
WebSockets are long-lived TCP connections that enable bi-directional, real-time communication between client and server.
Key characteristics:
- Both Workers and Durable Objects can act as WebSocket endpoints (client or server)
- WebSocket sessions are long-lived, making Durable Objects ideal for accepting connections
- A single Durable Object instance can coordinate between multiple clients (for example, chat rooms or multiplayer games)
Refer to Cloudflare Edge Chat Demo ↗ for an example of using Durable Objects with WebSockets.
The Hibernation WebSocket API reduces costs by allowing Durable Objects to sleep when idle:
- Clients remain connected while the Durable Object is not in memory
- Billable Duration (GB-s) charges do not accrue during hibernation
- When a message arrives, the Durable Object wakes up automatically
The Hibernation WebSocket API extends the Web Standard WebSocket API to reduce costs during periods of inactivity.
When a Durable Object receives no events (such as alarms or messages) for a short period, it is evicted from memory. During hibernation:
- WebSocket clients remain connected to the Cloudflare network
- In-memory state is reset
- When an event arrives, the Durable Object is re-initialized and its
constructorruns
To restore state after hibernation, use serializeAttachment and deserializeAttachment to persist data with each WebSocket connection.
Refer to Lifecycle of a Durable Object for more information.
To use WebSockets with Durable Objects:
- Proxy the request from the Worker to the Durable Object
- Call
DurableObjectState::acceptWebSocketto accept the server side connection - Define handler methods on the Durable Object class for relevant events
If an event occurs for a hibernated Durable Object, the runtime re-initializes it by calling the constructor. Minimize work in the constructor when using hibernation.
import { DurableObject } from "cloudflare:workers";
// Durable Objectexport class WebSocketHibernationServer extends DurableObject { async fetch(request) { // Creates two ends of a WebSocket connection. const webSocketPair = new WebSocketPair(); const [client, server] = Object.values(webSocketPair);
// Calling `acceptWebSocket()` connects the WebSocket to the Durable Object, allowing the WebSocket to send and receive messages. // Unlike `ws.accept()`, `state.acceptWebSocket(ws)` allows the Durable Object to be hibernated // When the Durable Object receives a message during Hibernation, it will run the `constructor` to be re-initialized this.ctx.acceptWebSocket(server);
return new Response(null, { status: 101, webSocket: client, }); }
async webSocketMessage(ws, message) { // Upon receiving a message from the client, reply with the same message, // but will prefix the message with "[Durable Object]: " and return the number of connections. ws.send( `[Durable Object] message: ${message}, connections: ${this.ctx.getWebSockets().length}`, ); }
async webSocketClose(ws, code, reason, wasClean) { // Calling close() on the server completes the WebSocket close handshake ws.close(code, reason); }}