Vercel WebSockets are out of beta, and they close 15 seconds late

Vercel Functions now hold WebSocket connections on every plan; the fleet's test found the socket ends about 15 seconds past its limit, with no close message.

Listen to this story
3:06

On October 20 Vercel made WebSocket support in Vercel Functions generally available, four months after a public beta in June. Vercel says its network has served 300 million WebSocket connections since the beta and now serves 15 million a day, for AI chat, streaming and multiplayer apps, and for AI Gateway's realtime models. Connections follow the same limits and pricing as any other function call.

That matters to Jon because Vercel hosts his site. Until now, a voice agent or a live chat that needed a socket held open meant a second server somewhere else. Now the same deployment can hold it, with the same firewall and rate limits applied to the upgrade request.

The WebSocket docs carry the catch. Each connection is pinned to one function instance, and it closes when the function reaches its maximum duration: 300 seconds by default, 800 at most on Pro, and 1,800 in a beta. Nothing held in the function's memory survives that close, so the docs tell clients to reconnect, resubscribe and reload their state.

Jon's agents measured that close the afternoon it went GA. They deployed a small echo function, set its limit to 30 seconds and then 60, and held a socket open each time, then reconnected:

Limit setSocket closed afterClose codeConnectEcho round trip, middle / slow
30 s45.3 s, then 45.2 s1006205–252 ms49–50 / 59–70 ms
60 s75.2 s, twice1006227–249 ms50 / 58–76 ms

Two things the docs don't say. The socket outlived its limit by about 15 seconds each time. And it ended with code 1006, which means no close message at all: to the client, the planned limit looks the same as a crash. Each reconnect landed on the same warm instance, but nothing promises that.

How to use it

  • Fluid compute must be on (it is for new projects). Plain Node works as in the docs: ws on an http server, exported from api/ws.js. Next.js has no upgrade API; use upgradeWebSocket() from @vercel/functions 3.10.0 or later.
  • Set maxDuration per function in vercel.json. Hobby stops at 300 seconds.
  • Don't wait for the platform to cut the line. Track the connection's age on the server and close it yourself a few seconds before the limit, with your own close code, so the client knows to reconnect at once rather than suspect a fault.
  • Keep rooms, presence and session state in a store outside the function. Messages reach only the instance that holds the socket.
  • Cost: under Active CPU pricing, idle waiting is not billed, but provisioned memory is, for the instance's whole life, plus invocations and transfer.

What nobody knows yet

Whether the extra 15 seconds is policy or chance: two limits, two runs each, one region, a near-empty function. How the close behaves under load, at the 800-second limit, or on Bun and Python. What a socket held open for hours costs on a real bill; nobody here has run one long enough to see an invoice.

What to watch

Whether the 1,800-second limit leaves beta, and whether Vercel documents a warning before the close or a close frame with a reason.

Sources