Skip redundant protocol parsing during raw streaming#1025
Open
drudolf wants to merge 2 commits into
Open
Conversation
execProtocolRawStream() consumers receive raw bytes via onRawData and never read #currentResults, but the write callback pushed every parsed message into it anyway. The array grew unbounded until the next execProtocol*() call happened to reset it, forcing raw-stream consumers (e.g. wire-protocol bridges) to issue periodic no-op protocol calls just to release the memory.
The WASM write callback ran the internal pg-protocol parser over every outbound chunk even in execProtocolRawStream() mode, eagerly decoding every DataRow field into strings that no one consumes — roughly half the latency of a raw-stream query. On the raw path the parse is load-bearing only for LISTEN/NOTIFY dispatch (errors and notices are not surfaced there), so skip it when no notification listeners are registered. The skip decision cannot change mid-query because execProtocolRawSync is synchronous, so the stateful parser always sees a query's chunks all-or-nothing.
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.
Problem
The WASM write callback unconditionally runs the internal pg-protocol parser over every outbound chunk and pushes the parsed messages into
#currentResults— including duringexecProtocolRawStream(), where the caller consumes raw bytes viaonRawDataand the parsed results are never read.For raw-stream consumers this means:
#currentResultsgrows unbounded until an unrelatedexecProtocol*()call happens to reset it, forcing raw-stream consumers to issue periodic no-op protocol calls just to release the memory.Change
Two commits, each with a changeset:
#currentResultson that path.execProtocolRawSyncis synchronous, so the stateful parser always sees a query's chunks all-or-nothing.Consumers of the parsed APIs (
query(),exec(),execProtocol*) are unaffected — verified as a benchmark control.Numbers
Measured downstream through prisma-pglite-bridge (Prisma → pg → wire protocol →
execProtocolRawStream),findManyover 100 rows, n=1000 iterations × 5 repeats, same engine version A/B:Commit 1 alone is memory hygiene (~no latency change); commit 2 is the latency win. Re-validated on this branch (PG 18.3) with the same profile.
pglite-socketshould benefit identically, since it serves the raw protocol.Validation
packages/pglitetest suite passes, includingexec-protocol.test.tsandtest:node(the only local failures were caused by my locally assembledrelease/artifacts lackingpg_stat_statements.tar.gz, which the published npm package excludes — unrelated to this change).typecheck,eslint,prettierclean.Relation to existing work
Independent of and compatible with #903 — that work optimizes the parsed-results pipeline; this PR fixes the raw path's cost model, which #903 doesn't cover.