pub const RELAY_BLOCK_SIZE: usize = _; // 65_536usizeExpand description
The block reads are cut from once the initial 16 KiB is used up.
§Why a block rather than a buffer
BytesMut::split hands the filled bytes on without copying them, which is
what keeps the relay allocation-light — but the piece handed on and the
piece kept share one heap block, and quinn holds its piece until the segment
carrying it has been acknowledged. So the memory a tunnel occupies is
blocks × block size, while the only thing bounding it — quinn’s
send_window, 10 MB per connection — counts bytes. Reserving a fresh
RELAY_BUF_SIZE block per read made every read, however small, pin 16 KiB:
11.7x amplification for MTU-sized reads and 238x for 64-byte ones.
§The arithmetic
A block is abandoned only once its remaining capacity falls below
RELAY_BUF_SIZE, so at least RELAY_BLOCK_SIZE - RELAY_BUF_SIZE = 48 KiB
of it has been handed to the client by then. Worst-case amplification is
therefore 64 / 48 = 1.33x whatever the read sizes are, against a factor that
grew without bound as reads got smaller.
§What it costs at rest
The trade is paid in resting size: a tunnel that has relayed a single byte
holds one whole block across every wait from then on, so an idle tunnel
costs 64 KiB rather than the 16 KiB it started with. Saturated at the
default limits – max_connections x max_targets_per_conn – that is
4 GiB, and at the ~20 live tunnels per connection seen in production about
1.3 MB per connection. The amplification is what produces the memory peaks
worth avoiding, and 1.33x beats 2x there; docs/configuration.md says the
same to operators.