Skip to content

perf(message_bus): batch small replica frames per socket read - #4224

Merged
spetz merged 3 commits into
masterfrom
feat/msg-bus-bufreadwrite
Sep 21, 2026
Merged

spetz merged 3 commits into
masterfrom
feat/msg-bus-bufreadwrite

Conversation

@hubcio

@hubcio hubcio commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

The link shard that owns a peer's replica socket burns a full
core under sustained replicated writes. Nothing batches its reads:
read_message issues one io_uring read for the 256-byte header and
a second for the body. Bytes already sitting in the kernel receive
queue wait for the next call.

A read-ahead buffer sized by message_bus.replica_read_buffer_size
lets one socket read serve a whole burst. It adds no latency, because
the reader never waits for the buffer to fill. One fill delivers
at most one buffer, so a body above that size crosses the buffer in
buffer-sized pieces and pays one extra pass over the payload and one
read per piece. A read that large goes straight into the frame's own
buffer instead.

Zero keeps the unbuffered path, so the A/B baseline is a config change
and not a separate build. The plaintext writer already coalesces into
one writev, so it is left alone.

replica_socket_reads_total and replica_inbound_frames_total carry the
evidence on the real workload: their ratio is the batching factor,
and only link shards bump them. A read counts once it completes,
so a link torn down mid-read cannot inflate the ratio.

@github-actions github-actions Bot added the S-waiting-on-review PR is waiting on a reviewer label Sep 18, 2026
@codecov

codecov Bot commented Sep 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.35065% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.95%. Comparing base (d1cb5ae) to head (436dc81).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
core/message_bus/src/framing.rs 97.77% 0 Missing and 1 partial ⚠️
core/message_bus/src/transports/tcp.rs 99.31% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             master    #4224       +/-   ##
=============================================
- Coverage     87.53%   73.95%   -13.58%     
  Complexity     1575     1575               
=============================================
  Files          1283     1282        -1     
  Lines        223461   204348    -19113     
  Branches     186824   167713    -19111     
=============================================
- Hits         195605   151133    -44472     
- Misses        23141    48550    +25409     
+ Partials       4715     4665       -50     
Components Coverage Δ
Rust Core 71.94% <94.18%> (-16.68%) ⬇️
Java SDK 68.68% <ø> (ø)
C# SDK 77.41% <ø> (ø)
Python SDK 90.97% <ø> (ø)
PHP SDK 85.67% <ø> (ø)
Node SDK 96.43% <ø> (+0.06%) ⬆️
Go SDK 70.18% <ø> (+0.13%) ⬆️
Files with missing lines Coverage Δ
core/configs/src/server_config/defaults.rs 100.00% <100.00%> (ø)
core/configs/src/server_config/displays.rs 100.00% <ø> (ø)
core/configs/src/server_config/message_bus.rs 98.92% <100.00%> (+0.55%) ⬆️
core/message_bus/src/config.rs 77.64% <100.00%> (+0.53%) ⬆️
core/message_bus/src/installer/replica.rs 88.26% <100.00%> (+0.21%) ⬆️
core/message_bus/src/lib.rs 97.66% <100.00%> (+0.08%) ⬆️
core/shard/src/lib.rs 85.71% <100.00%> (+0.19%) ⬆️
core/shard/src/metrics.rs 91.62% <100.00%> (+0.20%) ⬆️
core/message_bus/src/framing.rs 92.96% <97.77%> (+3.81%) ⬆️
core/message_bus/src/transports/tcp.rs 98.83% <99.31%> (+0.19%) ⬆️

... and 293 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hubcio
hubcio force-pushed the feat/msg-bus-bufreadwrite branch 3 times, most recently from f980b26 to 1c41571 Compare September 21, 2026 10:49
@hubcio hubcio changed the title feat(message_bus): read replica sockets ahead, bypassing large frames perf(message_bus): batch small replica frames per socket read Sep 21, 2026
The link shard that owns a peer's replica socket burns a full
core under sustained replicated writes. Nothing batches its reads:
read_message issues one io_uring read for the 256-byte header and
a second for the body. Bytes already sitting in the kernel receive
queue wait for the next call.

A read-ahead buffer sized by message_bus.replica_read_buffer_size
lets one socket read serve a whole burst. It adds no latency, because
the reader never waits for the buffer to fill. One fill delivers
at most one buffer, so a body above that size crosses the buffer in
buffer-sized pieces and pays one extra pass over the payload and one
read per piece. A read that large goes straight into the frame's own
buffer instead.

Zero keeps the unbuffered path, so the A/B baseline is a config change
and not a separate build. The plaintext writer already coalesces into
one writev, so it is left alone.

replica_socket_reads_total and replica_inbound_frames_total carry the
evidence on the real workload: their ratio is the batching factor,
and only link shards bump them. A read counts once it completes,
so a link torn down mid-read cannot inflate the ratio.
The comments claimed a body crossing the read-ahead buffer
pays at most one buffer of copying. That holds only for a
body of two buffers or more.

The bypass needs an empty buffer, and compio's read_exact
shrinks the caller slice as the read proceeds
(compio-io 0.10.1 src/read/ext.rs:168). The read that
finishes a body of one to two buffers therefore arrives
with less room than the buffer and refills instead of
bypassing, so the payload crosses the buffer whole.

Also record that 0, unlimited and none select the
unbuffered path, and write "handed to the dispatcher"
rather than "delivered" at shutdown: the reader drops
frames when the dispatch queue closed first.
@hubcio
hubcio force-pushed the feat/msg-bus-bufreadwrite branch from 1c41571 to 83539f5 Compare September 21, 2026 12:33
@spetz
spetz merged commit f0bd702 into master Sep 21, 2026
100 checks passed
@github-actions github-actions Bot removed the S-waiting-on-review PR is waiting on a reviewer label Sep 21, 2026
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.

4 participants