---
title: Use WebSockets
description: Serve WebSocket connections from Durable Objects, including the standard and Hibernation APIs.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/durable-objects/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# 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:

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 ↗](https://github.com/cloudflare/workers-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](https://developers.cloudflare.com/durable-objects/platform/pricing/) 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](https://developers.cloudflare.com/workers/runtime-apis/websockets/) 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](#websocketserializeattachment) and [deserializeAttachment](#websocketdeserializeattachment) to persist data with each WebSocket connection.

Refer to [Lifecycle of a Durable Object](https://developers.cloudflare.com/durable-objects/concepts/durable-object-lifecycle/) 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](https://developers.cloudflare.com/durable-objects/api/state/#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 ](#tab-panel-6023)
* [  TypeScript ](#tab-panel-6024)
* [  Python ](#tab-panel-6025)

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) {

    // With web_socket_auto_reply_to_close (compat date >= 2026-04-07), the runtime

    // auto-replies to Close frames. Calling close() is safe but no longer required.

    ws.close(code, reason);

  }

}


```

TypeScript

```

import { DurableObject } from "cloudflare:workers";


export interface Env {

  WEBSOCKET_HIBERNATION_SERVER: DurableObjectNamespace<WebSocketHibernationServer>;

}


// Durable Object

export class WebSocketHibernationServer extends DurableObject {

  async fetch(request: Request): Promise<Response> {

    // 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: WebSocket, message: ArrayBuffer | string) {

    // 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: WebSocket,

    code: number,

    reason: string,

    wasClean: boolean,

  ) {

    // With web_socket_auto_reply_to_close (compat date >= 2026-04-07), the runtime

    // auto-replies to Close frames. Calling close() is safe but no longer required.

    ws.close(code, reason);

  }

}


```

Python

```

from workers import Response, DurableObject

from js import WebSocketPair


# Durable Object


class WebSocketHibernationServer(DurableObject):

def **init**(self, state, env):

super().**init**(state, env)

self.ctx = state


    async def fetch(self, request):

        # Creates two ends of a WebSocket connection.

        client, server = WebSocketPair.new().object_values()


        # 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 `__init__` to be re-initialized

        self.ctx.acceptWebSocket(server)


        return Response(

            None,

            status=101,

            web_socket=client

        )


    async def webSocketMessage(self, 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(

            f"[Durable Object] message: {message}, connections: {len(self.ctx.get_websockets())}"

        )


    async def webSocketClose(self, ws, code, reason, was_clean):

        # With web_socket_auto_reply_to_close (compat date >= 2026-04-07), the runtime

        # auto-replies to Close frames. Calling close() is safe but no longer required.

        ws.close(code, reason)


```

Configure your Wrangler file with a Durable Object [binding](https://developers.cloudflare.com/durable-objects/get-started/#4-configure-durable-object-bindings) and [migration](https://developers.cloudflare.com/durable-objects/reference/durable-objects-migrations/):

* [  wrangler.jsonc ](#tab-panel-6032)
* [  wrangler.toml ](#tab-panel-6033)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "name": "websocket-hibernation-server",

  "durable_objects": {

    "bindings": [

      {

        "name": "WEBSOCKET_HIBERNATION_SERVER",

        "class_name": "WebSocketHibernationServer"

      }

    ]

  },

  "migrations": [

    {

      "tag": "v1",

      "new_sqlite_classes": ["WebSocketHibernationServer"]

    }

  ]

}


```

TOML

```

"$schema" = "./node_modules/wrangler/config-schema.json"

name = "websocket-hibernation-server"


[[durable_objects.bindings]]

name = "WEBSOCKET_HIBERNATION_SERVER"

class_name = "WebSocketHibernationServer"


[[migrations]]

tag = "v1"

new_sqlite_classes = [ "WebSocketHibernationServer" ]


```

A full example is available in [Build a WebSocket server with WebSocket Hibernation](https://developers.cloudflare.com/durable-objects/examples/websocket-hibernation-server/).

Local development support

Prior to `wrangler@3.13.2` and Miniflare `v3.20231016.0`, WebSockets did not hibernate in local development. Hibernatable WebSocket events like [webSocketMessage()](https://developers.cloudflare.com/durable-objects/api/base/#websocketmessage) are still delivered. However, the Durable Object is never evicted from memory.

### Automatic ping/pong handling

The Cloudflare runtime automatically handles WebSocket protocol ping frames:

* Incoming [ping frames ↗](https://www.rfc-editor.org/rfc/rfc6455#section-5.5.2) receive automatic pong responses
* Ping/pong handling does not interrupt hibernation
* The `webSocketMessage` handler is not called for control frames

This behavior keeps connections alive without waking the Durable Object.

### Batch messages to reduce overhead

Each WebSocket message incurs processing overhead from context switches between the JavaScript runtime and the underlying system. Sending many small messages can overwhelm a single Durable Object. This happens even if the total data volume is small.

To maximize throughput:

* **Batch multiple logical messages** into a single WebSocket frame
* **Use a simple envelope format** to pack and unpack batched messages
* **Target fewer, larger messages** rather than many small ones

* [  JavaScript ](#tab-panel-6036)
* [  TypeScript ](#tab-panel-6037)

JavaScript

```

import { DurableObject } from "cloudflare:workers";


// Define a batch envelope format


// Client-side: batch messages before sending

function sendBatch(ws, messages) {

  const batch = {

    messages,

    timestamp: Date.now(),

  };

  ws.send(JSON.stringify(batch));

}


// Durable Object: process batched messages

export class GameRoom extends DurableObject {

  async webSocketMessage(ws, message) {

    if (typeof message !== "string") return;


    const batch = JSON.parse(message);


    // Process all messages in the batch in a single handler invocation

    for (const msg of batch.messages) {

      this.handleMessage(ws, msg);

    }

  }


  handleMessage(ws, msg) {

    // Handle individual message logic

  }

}


```

TypeScript

```

import { DurableObject } from "cloudflare:workers";


// Define a batch envelope format

interface BatchedMessage {

  messages: Array<{ type: string; payload: unknown }>;

  timestamp: number;

}


// Client-side: batch messages before sending

function sendBatch(

  ws: WebSocket,

  messages: Array<{ type: string; payload: unknown }>,

) {

  const batch: BatchedMessage = {

    messages,

    timestamp: Date.now(),

  };

  ws.send(JSON.stringify(batch));

}


// Durable Object: process batched messages

export class GameRoom extends DurableObject<Env> {

  async webSocketMessage(ws: WebSocket, message: string | ArrayBuffer) {

    if (typeof message !== "string") return;


    const batch = JSON.parse(message) as BatchedMessage;


    // Process all messages in the batch in a single handler invocation

    for (const msg of batch.messages) {

      this.handleMessage(ws, msg);

    }

  }


  private handleMessage(

    ws: WebSocket,

    msg: { type: string; payload: unknown },

  ) {

    // Handle individual message logic

  }

}


```

#### Why batching helps

WebSocket reads require context switches between the kernel and JavaScript runtime. Each individual message triggers this overhead. Batching 10-100 logical messages into a single WebSocket frame reduces context switches proportionally.

For high-frequency data like sensor readings or game state updates, use time-based or count-based batching. Batch every 50-100ms or every 50-100 messages, whichever comes first.

Note

Hibernation is only supported when a Durable Object acts as a WebSocket server. Outgoing WebSockets do not hibernate.

Events such as [alarms](https://developers.cloudflare.com/durable-objects/api/alarms/), incoming requests, and scheduled callbacks prevent hibernation. This includes `setTimeout` and `setInterval` usage. Read more about [when a Durable Object incurs duration charges](https://developers.cloudflare.com/durable-objects/platform/pricing/#when-does-a-durable-object-incur-duration-charges).

### Extended methods

The following methods are available on the Hibernation WebSocket API. Use them to persist and restore state before and after hibernation.

#### `WebSocket.serializeAttachment`

* `` serializeAttachment(value ` any `) ``: ` void `

Keeps a copy of `value` associated with the WebSocket connection.

Key behaviors:

* Serialized attachments persist through hibernation as long as the WebSocket remains healthy
* If either side closes the connection, attachments are lost
* Modifications to `value` after calling this method are not retained unless you call it again
* The `value` can be any type supported by the [structured clone algorithm ↗](https://developer.mozilla.org/en-US/docs/Web/API/Web%5FWorkers%5FAPI/Structured%5Fclone%5Falgorithm)
* Maximum serialized size is 2,048 bytes

For larger values or data that must persist beyond WebSocket lifetime, use the [Storage API](https://developers.cloudflare.com/durable-objects/api/sqlite-storage-api/) and store the corresponding key as an attachment.

#### `WebSocket.deserializeAttachment`

* `deserializeAttachment()`: ` any `

Retrieves the most recent value passed to `serializeAttachment()`, or `null` if none exists.

#### Attachment example

Use `serializeAttachment` and `deserializeAttachment` to persist per-connection state across hibernation:

* [  JavaScript ](#tab-panel-6038)
* [  TypeScript ](#tab-panel-6039)

JavaScript

```

import { DurableObject } from "cloudflare:workers";


export class WebSocketServer extends DurableObject {

  async fetch(request) {

    const url = new URL(request.url);

    const orderId = url.searchParams.get("orderId") ?? "anonymous";


    const webSocketPair = new WebSocketPair();

    const [client, server] = Object.values(webSocketPair);


    this.ctx.acceptWebSocket(server);


    // Persist per-connection state that survives hibernation

    const state = {

      orderId,

      joinedAt: Date.now(),

    };

    server.serializeAttachment(state);


    return new Response(null, { status: 101, webSocket: client });

  }


  async webSocketMessage(ws, message) {

    // Restore state after potential hibernation

    const state = ws.deserializeAttachment();

    ws.send(`Hello ${state.orderId}, you joined at ${state.joinedAt}`);

  }


  async webSocketClose(ws, code, reason, wasClean) {

    const state = ws.deserializeAttachment();

    console.log(`${state.orderId} disconnected`);

    // With web_socket_auto_reply_to_close (compat date >= 2026-04-07), the runtime

    // auto-replies to Close frames. Calling close() is safe but no longer required.

    ws.close(code, reason);

  }

}


```

TypeScript

```

import { DurableObject } from "cloudflare:workers";


interface ConnectionState {

orderId: string;

joinedAt: number;

}


export class WebSocketServer extends DurableObject<Env> {

  async fetch(request: Request): Promise<Response> {

    const url = new URL(request.url);

    const orderId = url.searchParams.get("orderId") ?? "anonymous";


      const webSocketPair = new WebSocketPair();

      const [client, server] = Object.values(webSocketPair);


      this.ctx.acceptWebSocket(server);


      // Persist per-connection state that survives hibernation

      const state: ConnectionState = {

        orderId,

        joinedAt: Date.now(),

      };

      server.serializeAttachment(state);


      return new Response(null, { status: 101, webSocket: client });

    }


    async webSocketMessage(ws: WebSocket, message: string | ArrayBuffer) {

      // Restore state after potential hibernation

      const state = ws.deserializeAttachment() as ConnectionState;

      ws.send(`Hello ${state.orderId}, you joined at ${state.joinedAt}`);

    }


    async webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean) {

      const state = ws.deserializeAttachment() as ConnectionState;

      console.log(`${state.orderId} disconnected`);

      // With web_socket_auto_reply_to_close (compat date >= 2026-04-07), the runtime

      // auto-replies to Close frames. Calling close() is safe but no longer required.

      ws.close(code, reason);

    }


}


```

## WebSocket Standard API

WebSocket connections are established by making an HTTP GET request with the `Upgrade: websocket` header.

The typical flow:

1. A Worker validates the upgrade request
2. The Worker proxies the request to the Durable Object
3. The Durable Object accepts the server side connection
4. The Worker returns the client side connection in the response

Validate requests in a Worker

Both Workers and Durable Objects are billed based on the number of requests. Validate requests in your Worker to avoid billing for invalid requests against a Durable Object.

* [  JavaScript ](#tab-panel-6026)
* [  TypeScript ](#tab-panel-6027)
* [  Python ](#tab-panel-6028)

JavaScript

```

// Worker

export default {

  async fetch(request, env, ctx) {

    if (request.method === "GET" && request.url.endsWith("/websocket")) {

      // Expect to receive a WebSocket Upgrade request.

      // If there is one, accept the request and return a WebSocket Response.

      const upgradeHeader = request.headers.get("Upgrade");

      if (!upgradeHeader || upgradeHeader !== "websocket") {

        return new Response(null, {

          status: 426,

          statusText: "Durable Object expected Upgrade: websocket",

          headers: {

            "Content-Type": "text/plain",

          },

        });

      }


      // This example will refer to a single Durable Object instance, since the name "foo" is

      // hardcoded

      let stub = env.WEBSOCKET_SERVER.getByName("foo");


      // The Durable Object's fetch handler will accept the server side connection and return

      // the client

      return stub.fetch(request);

    }


    return new Response(null, {

      status: 400,

      statusText: "Bad Request",

      headers: {

        "Content-Type": "text/plain",

      },

    });

  },

};


```

TypeScript

```

// Worker

export default {

  async fetch(request, env, ctx): Promise<Response> {

    if (request.method === "GET" && request.url.endsWith("/websocket")) {

      // Expect to receive a WebSocket Upgrade request.

      // If there is one, accept the request and return a WebSocket Response.

      const upgradeHeader = request.headers.get("Upgrade");

      if (!upgradeHeader || upgradeHeader !== "websocket") {

        return new Response(null, {

          status: 426,

          statusText: "Durable Object expected Upgrade: websocket",

          headers: {

            "Content-Type": "text/plain",

          },

        });

      }


      // This example will refer to a single Durable Object instance, since the name "foo" is

      // hardcoded

      let stub = env.WEBSOCKET_SERVER.getByName("foo");


      // The Durable Object's fetch handler will accept the server side connection and return

      // the client

      return stub.fetch(request);

    }


    return new Response(null, {

      status: 400,

      statusText: "Bad Request",

      headers: {

        "Content-Type": "text/plain",

      },

    });

  },

} satisfies ExportedHandler<Env>;


```

Python

```

from workers import Response, WorkerEntrypoint


# Worker


class Default(WorkerEntrypoint):

async def fetch(self, request):

if request.method == "GET" and request.url.endswith("/websocket"): # Expect to receive a WebSocket Upgrade request. # If there is one, accept the request and return a WebSocket Response.

upgrade_header = request.headers.get("Upgrade")

if not upgrade_header or upgrade_header != "websocket":

return Response(

None,

status=426,

status_text="Durable Object expected Upgrade: websocket",

headers={

"Content-Type": "text/plain",

},

)


            # This example will refer to a single Durable Object instance, since the name "foo" is

            # hardcoded

            stub = self.env.WEBSOCKET_SERVER.getByName("foo")


            # The Durable Object's fetch handler will accept the server side connection and return

            # the client

            return await stub.fetch(request)


        return Response(

            None,

            status=400,

            status_text="Bad Request",

            headers={

                "Content-Type": "text/plain",

            },

        )


```

The following Durable Object creates a WebSocket connection and responds to messages with the total number of connections:

* [  JavaScript ](#tab-panel-6029)
* [  TypeScript ](#tab-panel-6030)
* [  Python ](#tab-panel-6031)

JavaScript

```

import { DurableObject } from "cloudflare:workers";


// Durable Object

export class WebSocketServer extends DurableObject {

  currentlyConnectedWebSockets;


  constructor(ctx, env) {

    super(ctx, env);

    this.currentlyConnectedWebSockets = 0;

  }


  async fetch(request) {

    // Creates two ends of a WebSocket connection.

    const webSocketPair = new WebSocketPair();

    const [client, server] = Object.values(webSocketPair);


    // Calling `accept()` connects the WebSocket to this Durable Object

    server.accept();

    this.currentlyConnectedWebSockets += 1;


    // Upon receiving a message from the client, the server replies with the same message,

    // and the total number of connections with the "[Durable Object]: " prefix

    server.addEventListener("message", (event) => {

      server.send(

        `[Durable Object] currentlyConnectedWebSockets: ${this.currentlyConnectedWebSockets}`,

      );

    });


    // When the client closes the connection, clean up the server side.

    // With web_socket_auto_reply_to_close (compat date >= 2026-04-07), the runtime

    // auto-replies to Close frames. Calling close() is safe but no longer required.

    server.addEventListener("close", (cls) => {

      this.currentlyConnectedWebSockets -= 1;

      server.close(cls.code, "Durable Object is closing WebSocket");

    });


    return new Response(null, {

      status: 101,

      webSocket: client,

    });

  }

}


```

TypeScript

```

// Durable Object

export class WebSocketServer extends DurableObject {

  currentlyConnectedWebSockets: number;


  constructor(ctx: DurableObjectState, env: Env) {

    super(ctx, env);

    this.currentlyConnectedWebSockets = 0;

  }


  async fetch(request: Request): Promise<Response> {

    // Creates two ends of a WebSocket connection.

    const webSocketPair = new WebSocketPair();

    const [client, server] = Object.values(webSocketPair);


    // Calling `accept()` connects the WebSocket to this Durable Object

    server.accept();

    this.currentlyConnectedWebSockets += 1;


    // Upon receiving a message from the client, the server replies with the same message,

    // and the total number of connections with the "[Durable Object]: " prefix

    server.addEventListener("message", (event: MessageEvent) => {

      server.send(

        `[Durable Object] currentlyConnectedWebSockets: ${this.currentlyConnectedWebSockets}`,

      );

    });


    // When the client closes the connection, clean up the server side.

    // With web_socket_auto_reply_to_close (compat date >= 2026-04-07), the runtime

    // auto-replies to Close frames. Calling close() is safe but no longer required.

    server.addEventListener("close", (cls: CloseEvent) => {

      this.currentlyConnectedWebSockets -= 1;

      server.close(cls.code, "Durable Object is closing WebSocket");

    });


    return new Response(null, {

      status: 101,

      webSocket: client,

    });

  }

}


```

Python

```

from workers import Response, DurableObject

from js import WebSocketPair

from pyodide.ffi import create_proxy


# Durable Object


class WebSocketServer(DurableObject):

def **init**(self, ctx, env):

super().**init**(ctx, env)

self.currently_connected_websockets = 0


    async def fetch(self, request):

        # Creates two ends of a WebSocket connection.

        client, server = WebSocketPair.new().object_values()


        # Calling `accept()` connects the WebSocket to this Durable Object

        server.accept()

        self.currently_connected_websockets += 1


        # Upon receiving a message from the client, the server replies with the same message,

        # and the total number of connections with the "[Durable Object]: " prefix

        def on_message(event):

            server.send(

                f"[Durable Object] currentlyConnectedWebSockets: {self.currently_connected_websockets}"

            )


        server.addEventListener("message", create_proxy(on_message))


        # When the client closes the connection, clean up the server side.

        # With web_socket_auto_reply_to_close (compat date >= 2026-04-07), the runtime

        # auto-replies to Close frames. Calling close() is safe but no longer required.

        def on_close(event):

            self.currently_connected_websockets -= 1

            server.close(event.code, "Durable Object is closing WebSocket")


        server.addEventListener("close", create_proxy(on_close))


        return Response(

            None,

            status=101,

            web_socket=client,

        )


```

Configure your Wrangler file with a Durable Object [binding](https://developers.cloudflare.com/durable-objects/get-started/#4-configure-durable-object-bindings) and [migration](https://developers.cloudflare.com/durable-objects/reference/durable-objects-migrations/):

* [  wrangler.jsonc ](#tab-panel-6034)
* [  wrangler.toml ](#tab-panel-6035)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "name": "websocket-server",

  "durable_objects": {

    "bindings": [

      {

        "name": "WEBSOCKET_SERVER",

        "class_name": "WebSocketServer"

      }

    ]

  },

  "migrations": [

    {

      "tag": "v1",

      "new_sqlite_classes": ["WebSocketServer"]

    }

  ]

}


```

TOML

```

"$schema" = "./node_modules/wrangler/config-schema.json"

name = "websocket-server"


[[durable_objects.bindings]]

name = "WEBSOCKET_SERVER"

class_name = "WebSocketServer"


[[migrations]]

tag = "v1"

new_sqlite_classes = [ "WebSocketServer" ]


```

A full example is available in [Build a WebSocket server](https://developers.cloudflare.com/durable-objects/examples/websocket-server/).

WebSocket disconnection on deploy

Code updates disconnect all WebSockets. Deploying a new version restarts every Durable Object, which disconnects any existing connections.

## Related resources

* [Mozilla Developer Network's (MDN) documentation on the WebSocket class ↗](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
* [Cloudflare's WebSocket template for building applications on Workers using WebSockets ↗](https://github.com/cloudflare/websocket-template)
* [Durable Object base class](https://developers.cloudflare.com/durable-objects/api/base/)
* [Durable Object State interface](https://developers.cloudflare.com/durable-objects/api/state/)

```

```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/durable-objects/","name":"Durable Objects"}},{"@type":"ListItem","position":3,"item":{"@id":"/durable-objects/best-practices/","name":"Best practices"}},{"@type":"ListItem","position":4,"item":{"@id":"/durable-objects/best-practices/websockets/","name":"Use WebSockets"}}]}
```
