Skip to content

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:

  1. Hibernation WebSocket API - Allows the Durable Object to hibernate without disconnecting clients when idle. (recommended)
  2. Web Standard WebSocket API - Uses the familiar addEventListener event pattern.

What are WebSockets?

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.

Why use Hibernation?

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

Durable Objects Hibernation WebSocket API

The Hibernation WebSocket API extends the Web Standard WebSocket API to reduce costs during periods of inactivity.

How hibernation works

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 constructor runs

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.

Hibernation example

To use WebSockets with Durable Objects:

  1. Proxy the request from the Worker to the Durable Object
  2. Call DurableObjectState::acceptWebSocket to accept the server side connection
  3. 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.

JavaScript
import { DurableObject } from "cloudflare:workers";
// Durable Object
export 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);
}
}