Repository navigation
fix: stop a connection from keeping every cursor it created - #1052
Open
vuanhphung wants to merge 1 commit into
Open
vuanhphung wants to merge 1 commit into
vuanhphung wants to merge 1 commit into
Conversation
Connection._cursors held every cursor ever created, so a long-lived connection grew by one closed cursor per query and close() walked all of them. Cursor.close() now removes its entry; Connection.close() still closes every cursor that is open. Signed-off-by: Vu Anh Phung <[email protected]> Co-authored-by: Isaac <[email protected]>
vuanhphung
temporarily deployed
to
azure-prod
November 13, 2026 20:20 — with
GitHub Actions
Inactive
vuanhphung
temporarily deployed
to
azure-prod
November 13, 2026 20:20 — with
GitHub Actions
Inactive
This was referenced Nov 14, 2026
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.
What type of PR is this?
Description
Connectionappended every cursor it created to_cursorsand never removed it, so a long-lived connection kept one closed cursor per query: 248 bytes each, about 50 MB after 200,000 queries, andconnection.close()then took 42 ms to walk them. Connections that run queries back to back for a long time (pools, services) grow without bound.Cursor.close()now drops its entry, and_cursorsis a dict used as an ordered set so that removal is O(1).Connection.close()still closes every cursor that is open (and its active result set), iterating over a copy. The change is inConnection/Cursor, so it applies to the Thrift, SEA and kernel backends alike.How is this tested?
A unit test for the Thrift and kernel backends checks that closed cursors leave
_cursors, that closing twice is fine, and thatconnection.close()still closes the open cursors and their result sets; it fails onmain. Full unit suite passes.One kernel connection to a local mock server, 200,000
cursor()/close()cycles (tracemalloc):connection.close()Throughput is unchanged: 200 threads x 30 s against the mock (20 ms server time, client and mock pinned to separate cores), 3 interleaved runs: 1336 / 1411 / 1411 QPS on main vs 1374 / 1337 / 1440 with this PR.
Live benchmark (staging Large Reyden warehouse)
TPC-H Q6 on a Large Real-Time warehouse, 800 sessions (4 processes x 200 threads), cold start, each session querying back to back for 120 s, 16 client cores. Isolated A/B: only this change vs connector main 0c1b9e8 + kernel 1.4.0, 3 interleaved rounds, nothing else on the warehouse. Measured at bec22d8. Median (min-max):
QPS within noise; memory drops because closed cursors are no longer retained (the gap grows with session length).
SELECT 1 on an X-Large Real-Time warehouse (driver-bound). Q6 above is limited by the warehouse, so the same harness also ran
SELECT 1, where the client is the limit: X-Large warehouse, 4 processes x 200 threads, 120 s, 16 client cores, this change vs connector main 0c1b9e8 + kernel 1.4.0, measured at bec22d8, run in rotation with the other factory PRs, 2 rounds. Median (min-max):Average QPS change per round: -0.2%, -1.0%.
Related Tickets & Documents
This pull request and its description were written by Isaac.