Skip to content

h2: bootstrap max streams from multi handle if in use - #22418

Closed
CatboxParadox wants to merge 1 commit into
curl:masterfrom
CatboxParadox:h2-max-streams-from-multi
Closed

h2: bootstrap max streams from multi handle if in use#22418
CatboxParadox wants to merge 1 commit into
curl:masterfrom
CatboxParadox:h2-max-streams-from-multi

Conversation

@CatboxParadox

Copy link
Copy Markdown
Contributor

From the description of CURLMOPT_MAX_CONCURRENT_STREAMS introduced in #3806 I'd expect the initial no. of concurrent streams CURL can send over one connection before a SETTINGS frame from the server is received would be tunable, but it isn't. For HTTP/2, it just bootstraps the value sent in curl's SETTINGS frame - but that applies to the server PUSH direction.

For my application, the situation improved a bit with #6852 but when the application goes from idle state (no connections) to having to process a sudden request peak (say thousands within few milliseconds), curl quickly spawns as many connections as allowed with CURLMOPT_MAX_TOTAL_CONNECTIONS (tens of connections; PIPEWAIT is set on each handle so each fills up to currently hard-coded 100 ctx->max_concurrent_streams before the next one is created) even though the server would've been perfectly OK with those thousands of open streams over one connection, just didn't manage to get a SETTINGS frame to curl in time.

Would this be an acceptable change?

If users don't set CURLMOPT_MAX_CONCURRENT_STREAMS, the default from multi->max_concurrent_streams is exactly the same (100) as the DEFAULT_MAX_CONCURRENT_STREAMS, so no change in behavior. If they do set it - with a different aim than mine - the comment from #6852 still applies:

The server can always reject new streams anyway if we go above what it accepts.

@icing

icing commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

I believe the original intent of CURLMOPT_MAX_CONCURRENT_STREAMS was to select fewer than the protocol defined 100 streams. Until the server side settings come in. To make curl use, let's say 10, instead of the max the server announces.

Using it in the other direction only really works if you already know the server has more. Otherwise the application risks getting many streams refused. But in a known setup, I can see how that would be advantageous.

Your change should be fine in both cases.

@CatboxParadox

Copy link
Copy Markdown
Contributor Author

Thanks. The way I understand this from the RFC, the existence of some "initial limit" itself is a bit unexpected, with values below 100 downright not recommended (emphasis mine):

SETTINGS_MAX_CONCURRENT_STREAMS (0x03):

This setting indicates the maximum number of concurrent streams that the sender will allow.
This limit is directional: it applies to the number of streams that the sender permits the receiver to create.
Initially, there is no limit to this value. It is recommended that this value be no smaller than 100, so as to not unnecessarily limit parallelism.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR makes HTTP/2 connection concurrency bootstrap from the multi handle’s configured CURLMOPT_MAX_CONCURRENT_STREAMS (when available) instead of always using DEFAULT_MAX_CONCURRENT_STREAMS. This allows applications to tune the initial per-connection concurrency assumption before the server’s SETTINGS frame is received, helping avoid premature connection fan-out during sudden request spikes.

Changes:

  • Initialize ctx->max_concurrent_streams from Curl_multi_max_concurrent_streams(data->multi) when data->multi is set.
  • Preserve existing default behavior (DEFAULT_MAX_CONCURRENT_STREAMS) when no multi handle is present.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@bagder bagder closed this in c7b1e10 Jul 29, 2026
@bagder

bagder commented Jul 29, 2026

Copy link
Copy Markdown
Member

Thanks!

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

Development

Successfully merging this pull request may close these issues.

4 participants