perf(noq-proto): lazily allocate remote stream slots#667
Merged
Conversation
Port of quinn-rs/quinn#2601. `StreamsState::new` used to eagerly insert `(id, None)` placeholder entries in both `send` and `recv` FxHashMaps for every remote stream id in `0..max_remote[dir]`. With `max_concurrent_*_streams = 10_000` (e.g. for MoQ relay nodes that burn through short-lived streams), hashbrown rounded each map's bucket array up to ~65K buckets, costing ~0.5-2 MB of bucket memory per Connection before any stream data was sent. Move that work into a lazy frontier-advance step at the top of each remote receive path. Remote stream state: - `id.index() >= max_remote[dir]`: not allowed - `id.index() >= next_remote[dir]`: allowed, absent from map - `id.index() < next_remote[dir]`, present: active - `id.index() < next_remote[dir]`, absent: closed RFC 9000 section 3.2 says receiving a frame for index N implicitly opens all lower indices. `ensure_remote` handles that by materializing `None` placeholders for every index in `[next_remote, id.index()]` - otherwise a late out-of-order frame for a skipped index would land on "absent from map" and get dropped as closed. Placeholders are short-lived: they get filled on first real access or removed when the stream closes, so unlike a growing "closed ids" set the map stays bounded by currently live streams even across heavy churn. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
matheus23
approved these changes
May 21, 2026
matheus23
left a comment
Member
There was a problem hiding this comment.
FWIW we merge upstream Quinn into noq every now and then. So this would've made it into noq after getting merged into Quinn anyways.
The good news is that by submitting this here now you're probably getting this PR into an earlier release (we're probably releasing again on Monday).
Member
|
I think the only failing CI is an action that wants to write a comment on this PR but can't because it was submitted from a fork or sth like that. |
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.
Port of quinn-rs/quinn#2601.
StreamsState::newused to eagerly insert(id, None)placeholder entries in bothsendandrecvFxHashMaps for every remote stream id in0..max_remote[dir]. Withmax_concurrent_*_streams = 10_000(e.g. for MoQ relay nodes that burn through short-lived streams), hashbrown rounded each map's bucket array up to ~65K buckets, costing ~0.5-2 MB of bucket memory per Connection before any stream data was sent.