---
title: "Cloudflare Durable Objects: WebSocket Fanout With Hibernation"
description: "Durable Objects became the cheapest way to fan out WebSocket events at planet scale in 2026. How hibernation works, when to use it, and the limits to plan around."
canonical: https://callsphere.ai/blog/vw1c-cloudflare-durable-objects-websocket-fanout-hibernation
category: "AI Infrastructure"
tags: ["WebSockets", "Cloudflare", "Durable Objects", "Scalability", "AI Infrastructure"]
author: "CallSphere Team"
published: 2026-03-28T00:00:00.000Z
updated: 2026-05-07T09:32:10.873Z
---

# Cloudflare Durable Objects: WebSocket Fanout With Hibernation

> Durable Objects became the cheapest way to fan out WebSocket events at planet scale in 2026. How hibernation works, when to use it, and the limits to plan around.

> Cloudflare's WebSocket Hibernation API turned an idle connection from "hold a process" to "hold a row in a database." That changes the math on stateful realtime fan-out.

## What problem do Durable Objects solve?

```mermaid
flowchart LR
  Browser["Browser / Phone"] -- "WebSocket /ws" --> LB["Load Balancer
sticky session"]
  LB --> Pod1["Node A · Socket.IO"]
  LB --> Pod2["Node B · Socket.IO"]
  Pod1 -- "pub/sub" --> Redis[("Redis cluster")]
  Pod2 -- "pub/sub" --> Redis
  Pod1 --> AI["AI Worker · OpenAI Realtime"]
  Pod2 --> AI
```

CallSphere reference architecture

They solve the "stateful WebSocket room without a server" problem. In a traditional architecture, every chat room or call session needs at least one process holding open WebSockets and routing messages between participants. Idle rooms still cost CPU and RAM. Durable Objects flip that: each room is a single-instance object on Cloudflare's edge, every WebSocket can hibernate while idle, and the platform charges you only when something actually happens.

The result is a fan-out primitive where one Durable Object can hold thousands of clients, you can spawn millions of objects, and the cost graph tracks active conversations instead of provisioned capacity.

## How does WebSocket Hibernation actually work?

A Durable Object opens WebSockets via `state.acceptWebSocket()` instead of the standard `server.accept()`. After accept, the object can return to dormancy. When a client sends a message, Cloudflare's runtime resurrects the object, calls `webSocketMessage(ws, msg)`, and lets it go back to sleep when done.

Three things change because of this:

1. **No billable duration during idle.** GB-second charges accrue only while the object is awake.
2. **Connection state survives hibernation.** Cloudflare keeps the TCP connection open and rehydrates state from `state.storage`.
3. **The 2026-04-07 compatibility flag** `web_socket_auto_reply_to_close` makes connection teardowns transition cleanly so you stop seeing zombie sockets in the CLOSING state.

For AI agents, this is gold for use cases like idle sessions waiting for the next utterance, multi-participant rooms with long pauses, and dashboard subscriptions where the user is logged in but not actively interacting.

## CallSphere's implementation

CallSphere uses Durable Objects for two specific surfaces:

- **Public-facing demo and trial dashboards.** A Durable Object per trial account holds the WebSocket subscription for live metrics. With 14-day trials and tens of thousands of historical signups, hibernation cut the bill versus a Socket.IO equivalent by about 80%.
- **Webhook fan-out for the affiliate program.** Each affiliate gets a DO holding their dashboard WebSocket; events from referred trial conversions wake the object briefly, fan out, and re-hibernate.

The core Sales Calling and Healthcare paths still use Socket.IO and OpenAI Realtime over WebSocket because they need server-side audio access and on-prem control. Durable Objects own the lighter surfaces where edge proximity and cost shape matter more than custom audio handling.

## Code: a hibernating fan-out room

```typescript
export class CallRoom {
  constructor(private state: DurableObjectState) {}

  async fetch(req: Request): Promise {
    const pair = new WebSocketPair();
    const [client, server] = Object.values(pair);
    this.state.acceptWebSocket(server);   // hibernation-aware
    return new Response(null, { status: 101, webSocket: client });
  }

  webSocketMessage(ws: WebSocket, msg: string) {
    for (const sock of this.state.getWebSockets()) {
      if (sock !== ws) sock.send(msg);
    }
  }

  webSocketClose(ws: WebSocket) { ws.close(); }
}
```

## Build steps

1. Set `compatibility_date = "2026-04-07"` or later in `wrangler.toml` to enable auto-close-handshake.
2. Define a Durable Object class and bind it from a Worker.
3. Use `state.acceptWebSocket(ws)` not `ws.accept()` to opt into hibernation.
4. Persist any cross-message state via `state.storage` because the object can hibernate between events.
5. Use `getWebSockets()` for fan-out instead of holding your own `Set`.
6. Set per-DO connection caps if your domain is multi-tenant — runaway tenants can otherwise spike GB-s.

## FAQ

**How many WebSockets per object?** Cloudflare advises planning for low thousands per DO, then sharding by chat room or session ID across many DOs.

**What happens during deploys?** Durable Objects relocate cleanly; clients see a brief reconnect. Implement reconnection with exponential backoff and you will not notice.

**Can I run AI inference inside a DO?** You can call out to Workers AI, OpenAI, or any HTTP endpoint. Long-running inference inside the DO event handler should be avoided — use Queues to push to a worker.

**How does pricing compare to Socket.IO on EC2?** Below 5k peak concurrent, DO is dramatically cheaper. Above 100k peak concurrent and constant traffic, a self-managed cluster still wins on per-message cost.

**Is the API stable?** As of 2026 yes — the hibernation API is GA and the auto-reply-to-close flag is the default.

CallSphere combines Cloudflare edge with our [115+ database tables](/pricing) for $149/$499/$1499 plans. Start the [14-day trial](/trial) or [book a demo](/demo).

## Sources

- [Use WebSockets (Durable Objects docs)](https://developers.cloudflare.com/durable-objects/best-practices/websockets/)
- [Build a WebSocket server with WebSocket Hibernation](https://developers.cloudflare.com/durable-objects/examples/websocket-hibernation-server/)
- [Cloudflare Durable Objects Release Notes](https://developers.cloudflare.com/durable-objects/release-notes/)
- [Durable Objects Overview](https://developers.cloudflare.com/durable-objects/)

---

Source: https://callsphere.ai/blog/vw1c-cloudflare-durable-objects-websocket-fanout-hibernation
