Repository navigation
Coalesce server messages into fewer writes - #20
Draft
nickamorim wants to merge 1 commit into
Draft
nickamorim wants to merge 1 commit into
nickamorim wants to merge 1 commit into
Conversation
Outside a StartBatch batch, every message written through buffer.Writer is its own write on the connection: a result costs one write system call per row, plus one for each protocol message around it, and with TCP_NODELAY each write is also its own packet. Add opt-in coalescing, modeled on the PostgreSQL backend's send buffer. With WriteBufferSize(n), complete messages are buffered per connection and written together when n bytes are pending, after ReadyForQuery, when the client sends Flush, before the server reads from the client, and when the connection ends. Reading only after flushing means a client can never wait on output the server is holding, including during authentication and COPY. Output is also written at most WriteBufferMaxDelay (default 1ms) after it is buffered, so rows written by a handler that then stalls still arrive; a negative delay gives the PostgreSQL behavior. The buffer is the one used by StartBatch, so coalesced protocol messages and materialized row batches leave in order, and batching behaves as before when coalescing is off. Writer.Write, used for frames encoded elsewhere such as pipelined responses, also goes through the buffer. Every write contains whole messages, and with coalescing a write error is sticky. The default remains one write per message. On loopback with a pgx client, 16 rows go from 19 writes to 1 per query (~318us -> ~96us) and 1024 rows from 1027 writes to 2 (~13.5ms -> ~0.39ms), with unchanged allocations. The full suite passes under -race with buffering forced on, and with it forced on without the delay bound.
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.
Adds opt-in
WriteBufferSize(n), which buffers complete messages per connection instead of writing each one separately. Buffered output is written oncenbytes are pending, afterReadyForQuery, on a clientFlush, before the server reads from the client, when the connection ends, and at mostWriteBufferMaxDelay(default 1ms) after buffering. The default is unchanged.StartBatchbuffer, so protocol messages and row batches stay in order.Writer.Writegoes through the buffer, keeping pipelined responses behind a bufferedRowDescription.-racewith buffering forced on for every server.Loopback, pgx client: