- Vercel
- /
- Vercel WebSockets vs Ably: fan-out, presence, and ordering compared
Vercel WebSockets vs Ably: fan-out, presence, and ordering compared
On June 22, 2026, Vercel announced WebSocket support for Vercel Functions in public beta. This means Vercel Functions can now accept and hold open a WebSocket connection natively, no workaround required. If you build on Vercel and reached for a third-party realtime provider mainly because Vercel couldn't hold a socket open, that constraint is gone.
But fan-out to multiple subscribers, presence, and guaranteed message ordering are still problems the connection alone doesn't solve. Vercel's function model also puts real limits on how far you can push that connection before you're building the rest yourself.
The rest of this piece breaks those down one at a time: exactly what Vercel's native WebSocket beta supports, where Ably's pub/sub layer picks up instead, and what changes for teams building production AI apps with the Vercel AI SDK.
Key takeaways
Vercel's native WebSocket connections don't fan out across instances by default. Broadcasting to multiple subscribers needs an external store like Redis, built and run by you.
Vercel's native WebSocket connections have no built-in presence primitive. Ably ships presence as one.
Vercel's native WebSocket connections preserve order within a single open connection, since that's what TCP itself guarantees. What's missing is any guarantee across reconnects, or across instances if you're fanning out via your own Redis coordination layer.
At a glance: fan-out, presence, and ordering compared
The table below compares the mechanisms that decide whether a raw WebSocket connection is enough on its own, or whether you need a dedicated pub/sub layer on top of it.
| Vercel Functions (native WebSocket, beta) | Ably Pub/Sub | |
|---|---|---|
| Bidirectional connection | Yes, a raw WebSocket pipe | Yes |
| Connection lifetime | Pinned to one function instance. 300 seconds by default, 800 seconds on Pro and Enterprise today, with an extended 1,800-second (30-minute) maximum in beta | Long-lived, no fixed cap |
| Fan-out to multiple subscribers | Not built in. Requires an external store, such as Redis, that you build and operate | Built in, to any number of subscribers |
| Message continuity on reconnect | Not built in. In-flight state is lost unless you build your own recovery | Automatic replay of missed messages on reconnect |
| Ordering and delivery guarantees | In order within a single connection, since that's what TCP guarantees. No guarantee across reconnects or between instances if fanning out via your own Redis coordination layer | Guaranteed ordering and exactly-once delivery |
| Presence (who's connected) | Not a built-in primitive | Built-in primitive |
| Global edge network | Function region-bound | 700+ points of presence |
| Client platforms | Wherever you can open a raw WebSocket | SDKs across web, mobile, IoT, and server |
How Vercel's native WebSocket support works
A WebSocket upgrade on Vercel is now a normal function invocation instead of an unsupported request type, and the connection stays pinned to whichever instance accepts it for as long as it's open. This requires Fluid compute, but as that's been the default for new Vercel projects since April 2025, most current projects already meet the requirement.
Because the upgrade behaves like a normal function invocation, most existing Node and Python socket libraries work unmodified. Next.js is the one exception: it has no built-in API for a WebSocket upgrade inside a route handler, so Vercel ships an experimental helper instead of native support.
Vercel's documentation gives the current shape of that helper, in app/api/ws/route.ts:
import {
experimental_upgradeWebSocket,
type WebSocketData,
} from '@vercel/functions';
export async function GET() {
return experimental_upgradeWebSocket((ws) => {
ws.on('message', (data: WebSocketData) => {
ws.send(data);
});
});
}This handles the upgrade and echoes each incoming message straight back. The experimental_ prefix is Vercel's own naming, not a caution added here. The API is explicitly called out as likely to change before general availability, and local development requires running vercel dev rather than next dev, since only the Vercel runtime injects the upgrade handler.
Where Vercel's WebSockets hit their limits in production
Two constraints show up quickly once you move past a simple demo using Vercel's native WebSocket support.
Duration cap. A WebSocket connection is a function invocation, so it inherits the function duration limit: 300 seconds by default, extending to 800 seconds on Pro and Enterprise plans today. An extended maximum of 1,800 seconds (30 minutes) is available in beta, though values above 800 seconds require function-level configuration and are only supported for specific Node.js and Python runtime versions. Anything that needs to stay open longer, for example a long support conversation, a slow-moving dashboard, or an idle chat session, has to reconnect on a schedule your application manages.
Connection pinning. A connection stays with the instance that accepted it for its entire lifetime. Durable, cross-connection state (presence, counters, shared rooms) needs to live in an external store such as Redis, since the function instance itself won't reliably hold it across scaling events or restarts.
Together, these are why native WebSocket support doesn't give you fan-out for free. Since each subscriber's connection can be pinned to a different Vercel Function instance, broadcasting one message to all of them means building the coordination layer yourself. Typically, that's a pub/sub channel in Redis that every Function instance subscribes to, relaying messages to whichever local connections match. That Redis fan-out pattern works, and plenty of teams already run it in production, but it's also infrastructure you now own, monitor, and scale on top of the function layer you were trying to simplify.
What Ably Pub/Sub adds for fan-out, presence, and ordering
Ably Pub/Sub builds fan-out, presence, and ordering into the channel itself, so you're not assembling them from separate pieces. Here's what each one actually gives you.
Fan-out. A publish reaches every subscriber connected to the channel, regardless of which of Ably's 700+ points of presence they connected through. Neither the publisher nor Ably's Pub/Sub servers need to know how many subscribers exist or where they are.
Presence. Clients enter and leave a channel's presence set, and every other subscriber sees state changes as they happen. No polling, no separate service to run.
Ordering and delivery. Message delivery is exactly-once per publisher, with guaranteed ordering from that publisher. Messages missed during a disconnect of up to two minutes replay automatically on reconnect. Persisted channel history extends that window to 24 to 72 hours, depending on your plan, though it needs to be enabled per namespace since it's not on by default.
None of this needs a separate coordination store. The channel does that job instead of Redis.
When Vercel's native WebSockets are enough, and when they're not
Works well for:
Session-scoped, single-instance interactions under 30 minutes
Cases where losing in-flight state on a reconnect is a minor inconvenience, not a real cost
Examples: a single client holding one ongoing conversation with your backend, or a short-lived control channel for one browser tab
Hits limits when:
Many subscribers need the same publish
Subscribers are spread across instances or regions
Delivery has to be guaranteed and in order
Connections need to stay open longer than a function invocation reasonably allows
Examples: live dashboards with more than a handful of viewers, chat rooms, collaborative tools with many participants, or anything with a compliance requirement around message delivery
Vercel's native WebSockets remove real friction for narrow, single-instance cases. They don't remove the need for a dedicated pub/sub layer once more than one subscriber, instance, or a longer-lived connection is involved.
What changes for production AI apps built on the Vercel AI SDK
One thing changes directly: cancel and steer signals, where a user interrupts or redirects an agent mid-response, now have a real bidirectional connection to travel over if you build directly on Vercel's raw socket, instead of depending on a side channel. That's a genuine improvement, and users notice it. An agent that stops the moment someone tells it to feels fundamentally different from one that keeps talking for another few seconds before catching up.
The harder problems don't change:
Resumable streaming. A dropped connection still needs to survive longer than the 30-minute function cap allows for anything but short interactions.
Multi-device continuity. A conversation following a user from laptop to phone isn't something a pinned, single-instance connection can provide on its own.
Human takeover. A support agent joining an existing conversation with full history intact depends on session state that outlives any single connection, which a raw socket doesn't give you.
Building directly on Vercel's raw socket also carries a lock-in cost. Your transport is coupled to one platform's function model, and teams that go this route often end up rebuilding it when they switch agent frameworks or extend the stack elsewhere. Ably has documented this pattern: Ada rebuilt its entire transport stack over 18 months after hitting this kind of wall, and Backline built roughly 30 microservices to handle message delivery before moving to dedicated infrastructure instead.
If any of that matters for what you're building, Ably's AI Transport provides a drop-in transport for the Vercel AI SDK's pluggable ChatTransport interface. It handles delivery over Ably's channel infrastructure instead of Vercel's function-level socket. The two aren't competing. Vercel's native WebSocket support gives you a faster, more direct path for the connection itself. AI Transport is the durable session layer above it, providing reconnection, multi-device continuity, and human handoff regardless of which transport carries the underlying connection.
Is Vercel's advice to use a third-party realtime provider still accurate?
Yes, for anything beyond a single-instance, session-scoped connection. Vercel's own knowledge base guide on adding pub/sub to a Vercel app still recommends third-party realtime providers, Ably among them. That's for use cases that need fan-out, presence, or guaranteed delivery. Native WebSocket support changes what's possible inside a single function instance. It doesn't change Vercel's own position on what a full realtime layer requires.
Boiled down, it comes to this: Vercel's native WebSocket support gives you a raw, bidirectional connection pinned to one function instance for up to 30 minutes, with no fan-out, presence, or ordering guarantees built in. Ably's pub/sub layer provides those three as properties of the channel itself, at the cost of running a dedicated realtime platform rather than a single function.
For AI apps built with the Vercel AI SDK specifically, Vercel's native WebSocket beta improves one interaction: cancel and steer signals reaching the right instance. It doesn't touch resumable streaming, multi-device continuity, or human takeover, since all three depend on session state that outlives any single connection.
Read the Ably Pub/Sub docs for the full details on channels, presence, and delivery guarantees, or the AI Transport docs if you're building on the Vercel AI SDK specifically. For a broader look at how WebSockets work as a protocol, see the WebSockets topic page.
Does Vercel support WebSockets?
Yes, as of the current beta. Vercel Functions can accept a WebSocket upgrade and hold the connection open, provided the project uses Fluid compute, which is the default for new projects. The connection is pinned to one function instance, with a default duration cap of 300 seconds, extending to 800 seconds on Pro and Enterprise plans today, or up to 1,800 seconds (30 minutes) as an extended maximum in beta.
What is the difference between SSE streaming and WebSocket on Vercel?
SSE is one-way, server to client only, and works over standard HTTP, which made it the default choice before native WebSocket support existed. WebSockets are bidirectional, letting the client send data back over the same connection without a separate request. Vercel now supports both. The choice depends on whether the client needs to send more than occasional control signals back to the server.
Is Vercel's new WebSocket beta a replacement for Ably?
Not for most production use cases. Native WebSocket support solves single-instance, session-scoped connections. It doesn't provide fan-out across instances, presence, or guaranteed ordering. That's why Vercel's own documentation continues to recommend third-party realtime providers, including Ably, for anything beyond that scope.
Now that Vercel supports WebSockets, do I still need a realtime provider?
It depends on what the connection needs to do. If it's a single, session-scoped connection under 30 minutes with one subscriber, Vercel's native support may be enough on its own. If you need to broadcast to multiple subscribers, guarantee delivery order, or maintain presence, you still need a dedicated pub/sub layer. That holds whether it comes from a provider like Ably or infrastructure you build and operate yourself.