WebSockets Arrive on Cloudflare Workers

Cloudflare Workers now supports WebSockets, enabling live, interactive use cases inside serverless applications. WebSockets let clients maintain a persistent, bidirectional connection to a server, which makes it possible to build features like real-time chat, live score tickers, and collaborative tools without repeated polling.

On their own, though, WebSockets are mainly a transport mechanism. To power interactivity, you need coordinated state alongside them. Durable Objects, currently in open beta, provide that stateful layer, and the two technologies are designed to work together: WebSockets handle the live connection, and Durable Objects handle the state that persists across requests and refreshes.

Establishing a WebSocket Connection

A Worker typically receives an HTTP request and returns a response. A WebSocket connection starts the same way — the client sends a request with an Upgrade header, indicating that it wants to switch protocols and open a WebSocket.

When that header is present, the Worker creates a WebSocketPair, which contains two WebSocket objects: one for the client and one for the server. The server-side socket is used for handling events, and the client socket is returned in the HTTP response along with a 101 status code (Switching Protocols) and the new webSocket property on the Response object.

On the server socket, the Worker calls accept(), which tells the runtime that the Worker is taking responsibility for managing the connection. From there, event listeners can be attached for message events (when data arrives) and close events (when the connection ends).

Client-Side Connection

Workers' WebSocket support is compatible with the browser's built-in WebSocket class, so no additional libraries are required on the client. A connection is opened by passing the Worker's URL to a new WebSocket() constructor, then listening for the standard open, message, and close events.

Stateful WebSockets with Durable Objects

A WebSocket connection by itself is stateless. If a user refreshes the page, any data sent over the connection is lost. Durable Objects provide the stateful API to change that. They allow Workers to read and update stateful data directly at the edge, without an external origin server or separate database.

This combination has been in the works since the Durable Objects private beta, when Cloudflare demonstrated a full chat application built with Workers, Durable Objects, and the then-preview WebSocket support. Durable Objects offer the storage primitives that make WebSockets useful in a distributed environment, and the two fit together naturally for latency-sensitive, real-time applications.

Getting Started Resources

Cloudflare has published two resources for developers who want to experiment with WebSockets on Workers:

  • A websocket-template with a simple HTML page demonstrating how to connect to a Worker-backed WebSocket, send and receive messages, and handle connection close and unknown data events. A live demo of the template is available.

  • Documentation covering WebSocket usage in Workers, including a learning guide and reference pages for the WebSocketPair API and the updated Response class that supports WebSocket upgrade responses.

Pricing and Current Considerations

WebSockets today incur a request charge when the connection is first established, followed by duration-based charges for as long as the connection remains active. There is no per-message fee. Durable Objects are not yet billed while in beta, so terminating a WebSocket inside a Durable Object is currently free.

One important note: passing a WebSocket through a Worker to another server or Durable Object will incur wall-clock duration charges for the entire lifespan of the connection, even if the Worker is not actively processing data. This is due to current platform limitations where the proxying Worker remains active for the duration of the connection. Cloudflare is working on eliminating duration charges for proxied WebSockets.

Until that fix is in place, developers who plan to use WebSockets with Durable Objects should route connections through a Worker on the Bundled plan rather than Unbound to avoid unexpected duration charges. Using Workers Unbound on a Worker that passes a WebSocket into a Durable Object is not recommended.

Going forward, Cloudflare is considering a pricing model for WebSockets terminated in Durable Objects that charges wall-clock time only when a message is being processed across any WebSocket connected to a given Durable Object, plus a much lower per-second active-connection fee when WebSockets are idle. Feedback on this pricing direction is being collected by the Cloudflare Workers product team.