Skip to content

Conversation

@rklaehn
Copy link

@rklaehn rklaehn commented Dec 12, 2025

Description

Coalesces small writes, while keeping large writes as separate slices.

E.g. you got iroh-blobs writing a bunch of hash pairs and then an entire 16 KiB chunk group. Writes will be this:

[u8;64]
[u8;64]
[u8;64]
...
[u8;64]
[u8;1024 * 16]

In this branch the SendBuffer won't store the [u8;64] as separate Bytes but will append the to the last_segment of the SendBuffer until that reaches the threshold of MAX_COMBINE (currently 1024).

This means that the actual segment buffer segments: VecDeque<Bytes> contains fewer elements and all those linear scans we do aren't that expensive.

If we get lucky and we get polled quickly enough, for small writes the data will never make it out of last_segment but will be copied right from there.

The next step would be to make sure the Bytes that are currently created when using AsyncWrite::write are not created. But that's for the next PR.

Todo: basic tests and proptests for SendBufferData

Breaking Changes

None

Notes & open questions

Q: Value for MAX_COMBINE? 1024 seems reasonable. This shouldn't be much more than what will be requested in poll_transmit.

@codecov-commenter
Copy link

codecov-commenter commented Dec 12, 2025

Codecov Report

❌ Patch coverage is 90.90909% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.30%. Comparing base (0234c4a) to head (5dd1399).

Files with missing lines Patch % Lines
quinn-proto/src/connection/send_buffer.rs 90.90% 2 Missing ⚠️
Additional details and impacted files
@@                 Coverage Diff                 @@
##           fix-send-buffer     #249      +/-   ##
===================================================
- Coverage            76.48%   76.30%   -0.19%     
===================================================
  Files                   83       83              
  Lines                23250    23266      +16     
===================================================
- Hits                 17783    17752      -31     
- Misses                5467     5514      +47     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@n0bot n0bot bot added this to iroh Dec 12, 2025
@github-project-automation github-project-automation bot moved this to 🏗 In progress in iroh Dec 12, 2025
extend_from_slice will *not* use existing buffer, but just reallocate
reserve will move existing data to the front before allocating
not necessary after all!
@github-actions
Copy link

github-actions bot commented Dec 16, 2025

Documentation for this PR has been generated and is available at: https://n0-computer.github.io/quinn/pr/249/docs/iroh_quinn/

Last updated: 2025-12-16T12:42:19Z

@flub flub added the performance Things that might improve performance both for iroh and as a normal QUIC library. label Dec 22, 2025
Copy link
Collaborator

@flub flub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anything needed here to unblock this work?

offset: u64,
/// Buffered data segments
segments: VecDeque<Bytes>,
/// Total size of `buffered_segments`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bufferred_segments doesn't exist, can we fix this up?

And also turn it into a real doc link so it doesn't end up being wrong so easily again. Our CI checks these things now.

}
// the rest has to be in the last segment
self.last_segment.advance(n);
// shrink segments if we have a lot of unused capacity
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should the last_segment ever be shrunk?

@flub
Copy link
Collaborator

flub commented Dec 22, 2025

Q: Value for MAX_COMBINE? 1024 seems reasonable. This shouldn't be much more than what will be requested in poll_transmit.

I guess with default MTUD probing config you go up to 1452 bytes per QUIC packet. A few of those will be taken up with the header and AEAD tag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance Things that might improve performance both for iroh and as a normal QUIC library.

Projects

Status: 🏗 In progress

Development

Successfully merging this pull request may close these issues.

5 participants