WebSockets on Cloudflare: Your Three Options in 2026

You want to run WebSockets on Cloudflare. Good instinct. The network is fast, the platform is well-built, and the operational track record is the one most other vendors are trying to inherit. The question is which of three different products you actually want, because "Cloudflare WebSockets" is not one thing.

This page is the honest answer. The three options are real, they fit different shapes of project, and the right one for you depends on what you are building and how much of the substrate you want to own.

Get started

Realtime made simple.

Free Tier: 500K broadcasts/mo and 100 concurrent across unlimited apps. $10/mo when you outgrow it.

Option 1: Workers + Durable Objects (DIY)

This is the Cloudflare-native, build-it-yourself path. Workers terminate the WebSocket connection at the edge. Durable Objects provide the stateful coordination layer that makes a non-trivial real-time feature actually work (per-room state, presence tracking, channel membership, ordering guarantees).

What you get:

  • Full control of the runtime. You write the connection handler, the message router, the auth layer, the disconnect cleanup, the reconnection coordination.
  • The Cloudflare network at no abstraction overhead. Connections terminate at the closest edge city; Durable Objects place themselves near the traffic.
  • Direct access to the rest of the Worker platform: KV, R2, D1, Queues, AI bindings. Real-time becomes one part of a larger Worker app.

What it costs you:

  • Engineering time. Multi-room chat, presence indicators, channel auth, message replay, reconnection handling, exponential backoff: all of these are problems Pusher and Soketi solved in 2011. Solving them again on Durable Objects is a real project. Most teams underestimate it.
  • Request and duration billing. Cloudflare applies a documented 20:1 ratio for incoming WebSocket messages in request billing: 100 incoming messages count as 5 billable requests. Durable Objects also charge for active duration unless WebSocket hibernation applies. Model both, because duration can dominate.

Pick this when: you have an unusual protocol need, you want to ship a real-time feature that is structurally different from channels-and-broadcasts, you have a strong team that wants to own the runtime, or you are building real-time as a core competence rather than as a means to ship a product feature.

Option 2: Cloudflare Realtime SFU

This one gets confused with the previous one because of the shared "realtime" word. Cloudflare Realtime is a Selective Forwarding Unit for WebRTC media. It routes audio and video between participants in a call. It is not a general-purpose WebSocket service.

What it is for: video calls, audio calls, live streams with low-latency participation, WebRTC-based collaboration tools where users send media (not just messages) to each other.

What it is not for: chat, presence, notifications, dashboards, multiplayer game state, typing indicators, live cursors. None of these are WebRTC media. None of these need an SFU.

If your project involves audio or video in real-time, Cloudflare Realtime is a serious option and is outside the scope of this page. If your project involves any other kind of real-time messaging, skip this option and read on.

Option 3: A Managed Pusher-Protocol Service on Cloudflare's Edge (Vask)

This is the option that did not exist a few years ago and now does. A managed WebSocket service running on Cloudflare's edge network, speaking the Pusher Channels protocol so your existing client SDKs work without modification.

What you get:

  • No Worker code, no Durable Object code, no DIY runtime. You configure a host and credentials. Your application code calls a standard Pusher SDK (pusher-js, laravel-echo, pusher-php-server, pusher-http-{language}). The runtime is managed.
  • The Cloudflare edge network as your real-time substrate. Connections terminate on Cloudflare's edge network.
  • Broadcast-priced, not Worker-priced. A broadcast to a channel is one broadcast on the bill, regardless of subscriber count. You are not modeling Worker requests, Durable Object duration, hibernation behavior, or storage for the broadcast path.
  • The Pusher protocol's SDK ecosystem. Every major language has a maintained SDK. Documented client and server semantics. Drop-in compatible with anyone moving off Pusher Channels or Soketi.

What you trade off:

  • You do not write the runtime. If your feature needs something the Pusher Channels protocol cannot express, this option is the wrong shape. (Most real-time features in production B2B and B2C apps fit cleanly inside the protocol's surface: public channels, private channels, presence channels, channel auth, broadcasts.)
  • You do not get direct access to the Workers platform from inside the broadcast pipeline. If you want a Worker-handled webhook to fire when a presence event occurs, you build that on your own application server (where you already have your business logic) rather than co-located in the broadcast handler.

Pick this when: the goal is to ship a real-time feature, not to ship a real-time runtime. When channels and broadcasts and presence are the surface area, and the engineering hours you would spend on rooms-on-DOs are better spent on the product itself. When you want Cloudflare's edge without inheriting the build cost of using it directly.

The decision in one frame

Are you building real-time as a core part of your product?
                            |
            ┌───────────────┴───────────────┐
           YES                              NO
            |                               |
   Is the feature shape          Skip to managed (Option 3).
   channels + broadcasts +       The build cost of DIY is not
   presence + channel auth?      justified for one feature.
            |
   ┌────────┴────────┐
  YES               NO
   |                 |
  Managed         Build on
  saves the       Workers +
  weeks.          Durable
  (Option 3)      Objects.
                  (Option 1)

The interesting case is the top-right of the tree: a team building real-time as a core product capability, on a use case that fits the Pusher protocol cleanly. For that team, managed-on-Cloudflare-edge is almost always the right call. The DIY option is justified when the use case does not fit the protocol, or when owning the runtime end-to-end is itself a strategic call.

What Vask actually is

Vask is a Pusher-protocol-compatible WebSocket service built on Cloudflare's edge. We did not invent a competing protocol because the Pusher Channels protocol already exists, is well-defined, and has a working SDK ecosystem. We did not build on AWS because the network and the operational story of Cloudflare's edge is the substrate we wanted to inherit.

The receipts:

  • Pusher Channels protocol on the wire. Same SDKs your codebase already speaks
  • Cloudflare-edge delivery in 330+ cities
  • Broadcast-priced. No Worker/Durable Object bill to model, no per-fan-out tax
  • Direct founder support on every paid tier
  • $10/mo entry tier (Side: 500 concurrent, 2M broadcasts). Indie at $20/mo. Pricing on the website

If you are evaluating Cloudflare for real-time and the use case fits the protocol, this is the option that gets you to shipping without writing Worker code or wiring Durable Objects.

When NOT to pick Vask on Cloudflare

Three cases where we would point you at a different option:

  • Your real-time feature does not fit the Pusher protocol. WebRTC signaling, MQTT-shaped IoT messaging, a proprietary wire format you cannot change: any of these mean the protocol is not a wedge for you. Build on Workers + Durable Objects, or pick a service that speaks the protocol you need.
  • You want to own the runtime as a strategic call. Regulated industries, research projects, teams whose product IS the real-time substrate: DIY on Workers + Durable Objects is the right answer. We are not for you.
  • You need WebRTC media routing. That is Cloudflare Realtime SFU's job, not ours.

If none of those apply, the math and the engineering-hours story work in your favor.

Does Cloudflare support WebSockets natively?
Yes. Cloudflare Workers and Durable Objects both support WebSocket connections. The Workers runtime handles connection acceptance, hibernation, and message handling. Durable Objects provide the stateful per-room or per-channel coordination layer. Cloudflare's network terminates the connection at the closest of 330+ edge cities.
What's the difference between Workers WebSockets, Durable Objects, and Cloudflare Realtime?
Workers handle the WebSocket connection lifecycle. Durable Objects provide the stateful coordination needed for any non-trivial real-time feature (chat rooms, presence, multiplayer state). Cloudflare Realtime SFU is a different product entirely; it is a Selective Forwarding Unit for WebRTC media (audio/video calls), not a general-purpose WebSocket service. If you want chat, presence, dashboards, or live notifications, you want Workers + Durable Objects, or a managed service on top.
What does it cost to run WebSockets on Workers + Durable Objects directly?
Workers and Durable Objects can be cost-effective, but the pricing model has details you need to model: incoming WebSocket messages are folded into request billing at Cloudflare's documented 20:1 ratio, and Durable Objects also charge for active duration unless hibernation applies. For realtime workloads, duration and hibernation behavior usually matter more than the request line item.
Why would I use a managed service on Cloudflare instead of DIY?
Three reasons most teams pick managed: (1) you save weeks or months of engineering time building rooms, presence, channel auth, and reconnection logic on top of Durable Objects. (2) You get a well-defined protocol (Pusher Channels) that your client SDKs already speak, so the integration is configuration not code. (3) You get a broadcast-priced service instead of modeling Worker requests, Durable Object duration, hibernation, and storage yourself. The DIY option is right when you want full control of the runtime or have an unusual protocol need; managed is right when the goal is shipping the product feature, not the substrate.
How does Vask fit into this?
Vask is a managed Pusher-protocol WebSocket service running on Cloudflare's edge. You get the Cloudflare network footprint and the Pusher protocol's mature SDK ecosystem without writing Worker or Durable Object code. It is the third option on the list above; we exist because DIY-on-Cloudflare is a lot of work most teams do not need to do.
When should I NOT use a managed service?
If your real-time use case is unusual enough that the Pusher Channels protocol does not fit (you need a different wire format, you are doing peer-to-peer signaling for WebRTC, you have hard requirements that lock you to a specific implementation), do not use a managed service that assumes the Pusher protocol. Build on Workers + Durable Objects directly. The same is true if owning the runtime end-to-end is itself the goal (research project, learning surface, regulated industry requiring full stack control).

Get going

The Cloudflare edge as your real-time substrate, the Pusher protocol as your wire format, your existing SDKs as your client.

Get on the edge

Realtime, re-architected for the edge.

Use Vask credentials, keep your existing client SDKs, and skip the Worker/Durable Object build.