Skip to content

fix(KNO-13857): reduce websocket reconnect load when connections can't recover#1031

Draft
kylemcd wants to merge 2 commits into
mainfrom
kyle-kno-13857-javascript-reduce-ws-retry-mechanism
Draft

fix(KNO-13857): reduce websocket reconnect load when connections can't recover#1031
kylemcd wants to merge 2 commits into
mainfrom
kyle-kno-13857-javascript-reduce-ws-retry-mechanism

Conversation

@kylemcd

@kylemcd kylemcd commented Jul 8, 2026

Copy link
Copy Markdown
Member

Description

Fixes KNO-13857 (follow-up to INC-408).

A customer rotated their public API key; their deployed clients kept the old one. Every websocket reconnect got a 403 that could never succeed, so each client retried forever — fleet-wide that was a ~1000% spike that saturated the sockets pods. The SDK can't stop a bad key, but it shouldn't turn one into a firehose. Three changes in packages/client fix that:

  • Backoff that actually slows down. Reconnects now escalate to a 10-min cap (was 30s), tracked in ApiClient so it survives the brief "open then drop" cycles that used to reset it. A dead connection settles to ~1 try / 5 min; the first ~6 attempts are unchanged, so real blips still recover fast.
  • Hidden tabs stop retrying. We already park hidden tabs after 30s, but only if connected — so a socket stuck mid-retry kept hammering in the background. Now it's parked too, and resumes when the tab is visible.
  • No more leaked sockets. teardown() always disconnects (even mid-retry), so a token refresh can't leave an old socket retrying forever with dead credentials.

Plus an online listener that reconnects immediately when the network returns, so the longer backoff doesn't strand real users.

Result: a stuck tab drops from ~401 reconnects to ~29 (foreground) / ~6 (hidden) over the incident window — a ~14–46× fleet reduction that turns the incident's +1000% into +27–71%. (Applies to clients that upgrade and redeploy.)

Checklist

  • Tests have been added for new features or major refactors to existing features.

Covered in test/api.test.ts and test/pageVisibility.test.ts. Full client suite (582 tests), type:check, lint, and format:check pass.

…t recover

Escalate the Phoenix socket reconnect backoff toward a 10-minute cap (was a
fixed 30s cap that Phoenix reset on every successful open), so a client that
can never reconnect - e.g. after an API key rotation leaves stale credentials
rejected on every upgrade - settles into a slow retry cadence instead of a
tight loop. The escalation survives brief "connect then immediately drop"
cycles and resets once a connection stays up for 30s.

Also:
- teardown() always disconnects the socket, even mid-reconnect, so a reauth
  that replaces the client can't leak a socket that retries forever.
- Hidden background tabs stop retrying: a socket mid-reconnect when the page
  is hidden is disconnected, not just connected ones, and resumes on visible.
- Reconnect promptly on the browser `online` event so recovery after a real
  network drop doesn't wait out the longer backoff.
@linear-code

linear-code Bot commented Jul 8, 2026

Copy link
Copy Markdown

KNO-13857

@changeset-bot

changeset-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b657fe1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@knocklabs/client Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
javascript-ms-teams-connect-example Ready Ready Preview, Comment Jul 8, 2026 4:34pm
javascript-nextjs-example Ready Ready Preview, Comment Jul 8, 2026 4:34pm
javascript-slack-connect-example Ready Ready Preview, Comment Jul 8, 2026 4:34pm
javascript-slack-kit-example Ready Ready Preview, Comment Jul 8, 2026 4:34pm

Request Review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b6bb977. Configure here.

Comment thread packages/client/src/api.ts
Addresses comment by @cursor: the `online` handler could revive a socket that
was cleanly/deliberately disconnected. Gate it on whether Phoenix wants to
reconnect (unclean drop or failed attempt), read from the close event's
`wasClean`, instead of on whether the socket was ever active.
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