Repository navigation
[buzz] Recover database pool capacity after stalled connections - #9267
Merged
Merged
Conversation
Bound SQLx connection returns so silent sockets cannot retain pool permits indefinitely. Keep reader checks inside the outer deadline and cover cancellation, recovery, reuse, and replenishment with real PostgreSQL. Co-authored-by: OpenAI Codex <noreply@openai.com> Signed-off-by: Helen Tian <htian@squareup.com>
Constrain SQLx version resolution, disable automated updates for its crate family, and reject manifest or lockfile changes that lose the reviewed patch in required CI. Co-authored-by: OpenAI Codex <noreply@openai.com> Signed-off-by: Helen Tian <htian@squareup.com>
htian-dev
marked this pull request as ready for review
November 9, 2026 01:11
htian-dev
temporarily deployed
to
codex-review
November 9, 2026 01:12 — with
GitHub Actions
Inactive
🔐 Codex Security Review
Review SummaryOverall Risk: NONE
FindingsNo concrete security, correctness, or reliability findings were identified. Notes
Generated by Codex Security Review | |
baxen
approved these changes
Nov 9, 2026
bostonaholic
added a commit
that referenced
this pull request
Nov 9, 2026
…ction-p * origin/main: (111 commits) feat(mobile): tag the reacted-to message author on reactions (#9141) fix(mobile): steady New DM picker rows and animate picks (#9249) perf(mobile): keep remote images on disk and show small ones as thumbnails (#9158) fix(relay): deliver slow cross-node events late instead of closing their recipients (#9235) fix(mobile): read only shown events from filtered Activity rows (#9215) fix(mobile): show the channel name as the notification subtitle (#9173) fix(mobile): keep Home's header clean under sheets (#9152) fix(mobile): show already-loaded custom emoji in the iOS reactions sheet (#9150) mobile: add follow and remind actions to inbox row menu (#9142) fix(mobile): start no threads in Solo chats (#9123) mobile: persist user profiles so names and avatars render on launch (#9116) fix(mobile): keep a sent thread reply above the composer (#9026) [buzz] Recover database pool capacity after stalled connections (#9267) feat: send a User-Agent on relay WebSocket upgrades (#9246) Record why relay connections close and quiet close warnings (#9245) fix(relay): say "channel owner or admin" in the call_webhook save refusal (#9169) feat(mobile): consolidate Solo chat settings in one sheet (#9255) fix(cli): preserve attachments across successive edits (#9226) fix(mobile): swipe left to reply so swipe-back keeps rightward drags (#9127) mobile: long-press a message link for open, copy and share (#9135) ... Signed-off-by: Matthew Boston <mboston@squareup.com>
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
https://linear.app/squareup/issue/BUZZ-656/relay-writer-pool-connections-stranded-after-a-burst-bb-public-2026-11
A short database interruption can leave the relay unable to handle database requests after traffic returns to normal. All connection slots can remain occupied even though no request is using them and PostgreSQL is idle. New requests then time out waiting for a slot.
Cause
SQLx, our database library, returns connections to the pool in a background task. If a socket stays open but stops answering, the final health check has no timeout. That task keeps its slot, and idle-connection cleanup cannot reclaim it (#4349).
Fix
Pin SQLx to
c3735abffrom PR #4407. After five seconds, it stops a stalled return operation, discards the connection, and frees the slot so new requests can open a replacement.Preserve the existing transaction rollback (#4394) and SQLite compatibility (#4402) fixes. Give the reader's own check four seconds so it can record its timeout before the outer deadline.
Critical risk
This fix depends on a SQLx patch that has not been merged. Its five-second limit affects every pool using this revision, so it can also discard slow but healthy connections and cause more reconnections. The local reproduction proves recovery from the injected failure; it does not establish production behavior.
Prevent accidental replacement: require SQLx
=0.9.0, disable Renovate updates for all seven crates, and fail required CI if the approved revision, lockfile source, or update restriction changes. These guards prevent version drift; they do not remove the runtime risk of the patch. An upgrade must explicitly update the policy after verifying all required fixes.Before and after evidence
With real PostgreSQL 17.6 on macOS arm64, a proxy silenced 100 existing connections while allowing new connections. All borrowers dropped their connections; PostgreSQL showed 100 idle sessions.
SELECT 1Captured before and after output
Before
After
Before evidence used Buzz
96af488d968a1ae9d961c2132bea27822735f8dawith SQLxf1e94ec3. After evidence used Buzz4bfe60197e8c390a8701053228cd50c5391f37d3with the SQLx pin committed inf253760085e24358728fa4f4fef059ccf892157f. These are local fault-injection results: they establish the stranded-slot mechanism and recovery, not what originally interrupted production database traffic.