Avoid setting recbuf/sndbuf in replica(_reader) processes - #237
Open
the-mikedavis wants to merge 1 commit into
Open
the-mikedavis wants to merge 1 commit into
the-mikedavis wants to merge 1 commit into
Conversation
|
Tick the box to add this pull request to the merge queue (same as
|
lukebakken
self-requested a review
August 12, 2026 20:45
osiris_replica and osiris_replica_reader set recbuf/sndbuf via
setsockopt, about 2 MiB for recbuf and 1.4 MiB for sndbuf. This requests
these buffer sizes from the kernel, but the kernel's settings
net.core.rmem_max/wmem_max default to about 224 kiB. These kernel
settings clamp the requested buffer sizes to those values.
Explicitly requesting these options actually does more harm than good.
Requesting them at all sets SOCK_RCVBUF_LOCK/SOCK_SNDBUF_LOCK which turn
kernel autotuning off for that socket, even though tcp_rmem and tcp_wmem
allow growth to several MiB. If the net.core.rmem_max/wmem_max are not
increased from their defaults, the replication sockets are clamped down
to 224 kiB instead of increased. If we _do not_ set the options, the
buffer sizes tune automatically and increase past the 224 kiB default.
This change avoids setting recbuf/sndbuf unless the options are
explicitly configured (replica_recbuf/replica_sndbuf app env). This
change doesn't affect the setting of the userspace buffers within
Erlang.
Testing
==
On an m7g.16xlarge 3-node cluster, the stock sysctls are:
net.core.rmem_max = 229376 net.core.wmem_max = 229376
net.ipv4.tcp_rmem = 4096 87380 6291456
net.ipv4.tcp_wmem = 4096 20480 4194304
net.ipv4.tcp_moderate_rcvbuf = 1
With a single in-VPC producer in the same AZ, 8192 byte messages, stock
--confirms (10000), a fresh stream per run, four runs per configuration,
60 seconds each, TLS connections terminated by the broker:
| scenario | env override | mean MiB/s | Δ vs fix
|--- |--- |--- |---
| this change | none | 561.1 | N/A
| pre-change `recbuf` behavior | `replica_recbuf=2041500` | 285.6 | -49.1%
| pre-change `sndbuf` behavior | `replica_sndbuf=1469880` | 508.2 | -9.4%
`ss` on the leader's replication sockets, mid-run:
| scenario | cwnd | wscale | rwnd_limited | sndbuf_limited
|--- |--- |--- |--- |---
| fix | 70–108 | 7,7 | 0% | 27–33%
| `replica_recbuf` forced | 41–42 | 2,7 | 98–100% |
| `replica_sndbuf` forced | 72–75 | 7,7 | 0% | 26–33%
Separately, if we use Osiris unpatched and tune net.core.rmem_max and
net.core.wmem_max together, we see strong growth from small increases,
converging on the throughput ceiling at around 1 MiB. This test used
three c6gn.xlarge clients all within the same AZ as the writer, all
targeting the same stream:
| rmem and wmem | mean MiB/s | CV
|--- |--- |---
| default (229376) | 378.1 | 1.1%
| 512 KiB | 567.5 | 0.6%
| 1 MiB | 579.0 | 0.1%
| 2 MiB | 579.8 | 0.3%
| 4 MiB | 580.7 | 0.1%
| 8 MiB | 581.3 | 0.1%
| 16 MiB | 580.4 | 0.1%
| 32 MiB | 581.1 | 0.1%
| 64 MiB | 580.1 | 0.4%
Publisher confirmation latency also falls by about half with this change
at these throughputs.
lukebakken
force-pushed
the
md/no-socket-opts
branch
from
August 12, 2026 21:08
cdb2d42 to
59afb47
Compare
Collaborator
Author
|
I ran iperf3 between these m7g.16xlarge instances and it seems that this 580 MiB/sec is the best we can do on a single connection that spans AZs. Max throughput according to iperf3 on even the network-optimized client instances (c6gn.xlarge) is identical. Ah, the ~5 Gbps is documented:
Let me see how far this can push with ENA Express (25 Gbps). |
Collaborator
Author
|
Looks like the cap for a single stream is 985-995 MiB/s with ENA express. I got that driven by two clients (same c6gn.xlarge). Adding additional clients doesn't move the needle. |
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.
osiris_replica and osiris_replica_reader set recbuf/sndbuf via setsockopt, about 2 MiB for recbuf and 1.4 MiB for sndbuf.
osiris/src/osiris_replica_reader.erl
Line 14 in 492bee9
osiris/src/osiris_replica.erl
Line 92 in 492bee9
This requests these buffer sizes from the kernel, but the kernel's settings net.core.rmem_max/wmem_max default to about 224 kiB. These kernel settings clamp the requested buffer sizes to those values. Explicitly requesting these options actually does more harm than good. Requesting them at all sets SOCK_RCVBUF_LOCK/SOCK_SNDBUF_LOCK which turn kernel autotuning off for that socket, even though tcp_rmem and tcp_wmem allow growth to several MiB. If the net.core.rmem_max/wmem_max are not increased from their defaults, the replication sockets are clamped down to 224 kiB instead of increased. If we do not set the options, the buffer sizes tune automatically and increase past the 224 kiB default.
This change avoids setting recbuf/sndbuf unless the options are explicitly configured (replica_recbuf/replica_sndbuf app env). This change doesn't affect the setting of the userspace buffers within Erlang.
Testing
On an m7g.16xlarge 3-node cluster, the stock sysctls are:
With a single in-VPC producer (c6gn.xlarge) in the same AZ, 8192 byte messages, stock --confirms (10000), a fresh stream per run, four runs per configuration, 60 seconds each, TLS connections terminated by the broker:
recbufbehaviorreplica_recbuf=2041500sndbufbehaviorreplica_sndbuf=1469880sson the leader's replication sockets, mid-run:replica_recbufforcedreplica_sndbufforcedSeparately, if we use Osiris unpatched and tune net.core.rmem_max and net.core.wmem_max together, we see strong growth from small increases, converging on the throughput ceiling at around 1 MiB. This test used three c6gn.xlarge clients all within the same AZ as the writer, all targeting the same stream:
Publisher confirmation latency also falls by about half with this change at these throughputs.