Skip to content

Host: one shared Neon Realtime client per address for every live read - #4403

Merged
luke-agent[bot] merged 1 commit into
mainfrom
luke/realtime-shared-client
Oct 21, 2026
Merged

luke-agent[bot] merged 1 commit into
mainfrom
luke/realtime-shared-client

Conversation

@charleslpan

@charleslpan charleslpan commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Before this, every liveRows read in the host opened its own Realtime client and socket. Neon's guide says to create one client for the whole app, because every subscription shares its connection (subscribing).

Supersedes #3287 with the same approach, rebuilt on main's live-follow.ts. #3287 doesn't rebase cleanly onto today's tree.

  • shareLiveClients keeps one client per Realtime URL, handed out as handles. It's loaded once however many reads wait on it. If loading fails it's forgotten, so the next read loads it again. The client closes when its last handle lets go. openRealtimeClient is this shared opener, so every area's liveRows uses it without other changes.
  • When the connection fails, Neon moves every subscription on the client to error and the client can't reconnect. So when any subscription on the shared client goes to error, the client is forgotten. The next subscribe or resubscribe opens a new one, and the old one closes once nothing holds it.
  • A sign-out or account switch (compose-account.ts's account change) calls dropRealtimeClients(). The next read opens a fresh client.
  • The polling fallback, renewals and sign-out handling in liveRows are unchanged.

A decision: the client is replaced on any error, not only a connection-level one. The client's connection error codes include whatever the server sends, so they can't be listed reliably. A per-subscription error such as a decode failure therefore costs one extra client, and the old client keeps serving the reads that hold it.

Tests (live-follow.test.ts): two reads share one client and it closes after the last one; a connection error makes the next read open a new client and the old one closes; sign-out (drop) drops the client; a failed load is retried. @luke/host tests and typecheck pass.

Made with Luke

View guided diff Turn on auto-fix

Every liveRows read at one Realtime URL now shares one client and its socket,
as Neon's guide prescribes. A client whose subscription moves to error is
replaced for the next read and closed once its last read lets go; a sign-out
or account switch drops the shared client.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
@vercel

vercel Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
luke-web Ready Ready Preview Oct 21, 2026 6:28pm UTC

Request Review

@luke-agent
luke-agent Bot marked this pull request as ready for review October 21, 2026 18:30
@luke-agent
luke-agent Bot added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit de5ae68 Oct 21, 2026
11 checks passed
@luke-agent
luke-agent Bot deleted the luke/realtime-shared-client branch October 21, 2026 18:42

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

This branch was successfully deployed

1 active deployment
Preview — a025c9dc Deployed Oct 21, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant