Ably, a realtime messaging platform built on pub/sub architecture, just dropped a custom transport layer for the Vercel AI SDK that exposes features HTTP-based SSE simply can't deliver. The team at Ably realized their realtime infrastructure was uniquely positioned to solve some fundamental limitations in how AI responses get delivered to clients—and they were right.
Why Default Transport Falls Short
The Vercel AI UI SDK's default transport runs over HTTP with Server-Sent Events (SSE), which made sense for a serverless platform company. But SSE has structural problems that become obvious once you try building anything beyond basic single-user chat. It doesn't support multi-device scenarios—if you're logged in on your phone and laptop simultaneously, only one gets the response. It's not multi-user either; multiple users chatting with the same bot can't see each other's messages. Cancellation is broken by design since HTTP SSE is unidirectional—closing the connection doesn't cleanly terminate the stream, leaving buffered chunks arriving after you've supposedly stopped.
Fighting useChat's Single-Request Mental Model
The real challenge wasn't the transport protocol itself—it was that useChat, the main React hook in the AI UI SDK, assumes a clean one-request-one-response flow. It tracks one active response at a time using an internal state machine: submitted → streaming → ready. This breaks immediately when you want multiple users participating in a single conversation or multiple responses arriving for a single prompt. "We built around the limitations," Ably explains, "by tracking 'own-turns' (prompts from this client) and 'observer-turns' (prompts from other clients)." Own-turns go through normal lifecycle hooks; observer-turns get injected directly via setMessages(...), a backdoor that bypasses the state machine entirely.
The setMessages Backdoor Strategy
Ably's solution leverages setMessages(...) to force conversation state updates across all connected clients, but this approach sacrifices built-in features like lifecycle hooks and tool-call notifications. When an observer-turn arrives while an own-turn is still streaming, Ably has to buffer it because the state machine can't handle interleaved responses from multiple sources. "It's a square peg and a round hole," they admit. "useChat was never designed to support these kinds of features."
What Gets Unlocked with Realtime Transport
Strip away HTTP's constraints and bolt on Ably's pub/sub channels, and suddenly you get multi-device automatic fan-out, genuine multi-user conversations where any participant can submit prompts, resumable streams that reconnect mid-response, human handoff support (a real person can take over mid-conversation), interruption and barge-in capabilities, and history compaction that transforms streaming tokens into clean messages for clients joining late. The Ably AI Transport also exposes useClientTransport and useView hooks that bypass useChat's state machine entirely while maintaining Vercel's stream format.
Key Takeaways
- HTTP/SSE transport is fundamentally limited for anything beyond single-user, single-device chat
- useChat's single-request/single-response assumption creates real friction when building collaborative AI experiences
- The setMessages(...) backdoor works but sacrifices lifecycle hooks and tool-call support
- Ably provides escape hatches (useClientTransport, useView) if you don't want to fight the state machine
- Realtime pub/sub infrastructure solves cancellation, resumption, and multi-user coordination at the transport layer