Skip to content

Vercel Finally Does WebSockets — Mind the Asterisks

Fluid Compute now holds sockets open natively, but duration caps, fan-out, and Next.js are still your problem.

Ji-ho Choi
Ji-ho Choi
Security & Cloud Editor · Jul 28, 2026 · 4 min read
Vercel Finally Does WebSockets — Mind the Asterisks

For roughly a decade, "can I run WebSockets on Vercel?" had a one-word answer, and an entire cottage industry grew up around the "no." Pusher, Ably, PartyKit, and most recently Rivet's outbound-tunneling gateway all existed, at least in part, because serverless platforms couldn't hold a socket open. On June 22, Vercel shipped native WebSocket support for Vercel Functions in public beta, and the honest read is: this genuinely closes the gap for one class of app, and genuinely doesn't for another. Knowing which class you're in is the whole game.

What actually changed

The enabler is Fluid Compute, Vercel's runtime model that has been the default for new projects since April 2025. Classic Lambda-style serverless maps one request to one short-lived container, which is structurally incompatible with a connection that lives for minutes. Fluid instances handle many concurrent requests and stick around, so an instance can accept a WebSocket upgrade and keep servicing it. Each connection is pinned to the instance that accepted it for the connection's lifetime; one instance can hold many connections.

The developer experience is better than you'd expect from a beta. You don't get a proprietary realtime SDK — you get plain Node.js. Export an http.Server with the standard ws package attached, or Socket.IO, Express, Hono, h3, or Nitro. Python works too: FastAPI over ASGI, Django Channels, Flask-Sock. The upgrade request passes through middleware, firewall rules, and rate limits like any other GET, so your existing auth and abuse controls apply before the socket opens.

One Socket.IO footgun worth flagging: you must force transports: ['websocket'] on the client. Socket.IO defaults to HTTP long-polling, which still doesn't map cleanly onto function invocations.

The Next.js irony

Here's the part that should make Vercel a little uncomfortable: the framework with the roughest support is their own. Next.js has no API for handling connection upgrades, so on Vercel you reach for experimental_upgradeWebSocket() from @vercel/functions — an explicitly experimental escape hatch — while Nitro, Nuxt, Express, and FastAPI apps deploy with zero platform-specific code. If you're on Next.js and this matters to you, the pragmatic move is to put the socket endpoint in a standalone api/ function using ws directly and keep Next.js out of it.

That inversion tells you something about where this feature came from. It's not a Next.js feature; it's an infrastructure capability that standard servers pick up for free, which is exactly the right design. The frameworks that behave like normal Node servers win.

Where it's genuinely enough

The sweet spot is session-scoped, bidirectional connections: an AI chat where the user interrupts mid-generation, an agent streaming tool-call progress, a live-updating dashboard for one user, collaborative cursors in a document with a handful of participants. For these, the old architecture — a Railway or Fly.io box running Socket.IO, plus Redis pub/sub, plus deployment coordination between your Vercel frontend and your socket server — was a lot of ceremony for "push tokens to a browser tab."

The pricing model fits this shape well. With Active CPU billing, you pay for CPU while processing messages, not while a connection sits idle — a socket that's open but quiet isn't burning CPU dollars the way a dedicated always-on server is. Two caveats before you assume it's near-free: provisioned memory time and data transfer still meter while instances are alive, and every open connection is a live instance somewhere. Watch the first month's bill rather than extrapolating from the changelog.

Where it runs out

Three walls, and they're load-bearing.

Connections die on a timer. A WebSocket closes when the function hits its max duration: 300 seconds default (and the hard cap on Hobby), 800 seconds on Pro and Enterprise, 1,800 seconds behind a separate beta. There's no hibernation. Your client needs reconnect-with-backoff, resubscribe, and state-reload logic as a first-class feature, because on the free tier every user reconnects at least every five minutes by design.

There's no broadcast primitive. A connection is pinned to one instance, and Vercel gives you no built-in way to reach connections held by other instances. Reconnecting clients can land anywhere, and during a deploy old connections drain on the previous deployment while new ones hit the new code. So presence, rooms, and fan-out mean Redis pub/sub with every instance subscribing — you're back to building the distributed-systems part yourself, just without managing the server underneath.

The competition solved a harder problem. Cloudflare's Durable Objects give each room a single globally-addressable stateful object, and WebSocket hibernation keeps connections open while the object sleeps — no duration cap, no external pub/sub for room state. Rivet's actor model, which it tunneled onto Vercel Functions before native support existed, makes the same bet: realtime apps want addressable state, not just open sockets. Vercel shipped the socket and left the state as an exercise for the reader. That's a defensible v1, but it's a v1.

The verdict

This is a real capability, not marketing — the "Vercel can't do WebSockets" objection is now dead for session-scoped realtime, and a meaningful number of small Socket.IO servers on Fly and Railway will quietly disappear because of it. If your realtime need is one client talking to its own backend, migrate; the operational win is immediate.

But don't mistake it for a realtime platform. The moment you need fan-out across thousands of clients, presence, ordering guarantees, or connections that outlive 30 minutes, you're either rebuilding that layer on Redis or paying a managed provider — and vendors like Ably are correctly pointing out that their pitch survives this launch intact. The interesting question for the next year is whether Vercel stops at "sockets work" or follows Cloudflare toward addressable state. Until then: great for conversations, not yet for crowds.

Sources & further reading

  1. WebSocket support is now in Public Beta — vercel.com
  2. WebSockets - Vercel Functions docs — vercel.com
  3. Vercel Functions Limits — vercel.com
  4. WebSockets on Vercel: native support, limits, and your options — ably.com
  5. How We Built WebSocket Servers for Vercel Functions — rivet.dev
  6. WebSockets on Vercel Functions: Real-Time Without a Separate Server — dev.to
Ji-ho Choi
Written by
Ji-ho Choi · Security & Cloud Editor

Ji-ho covers the increasingly tangled overlap between cloud architecture and security, drawing on a background as a penetration tester to keep his reporting grounded in real-world attack paths. He never lets a vendor claim go unquestioned and insists that every buzzword come with a proof of concept.

Discussion 0

Join the discussion

Sign in or create an account to comment and vote.

No comments yet

Be the first to weigh in.

Related Reading