Skip to content

Minimalistic HTTP2 flow control API #53372

@antonfirsov

Description

@antonfirsov

This is a replacement (next iteration) of #49897

Background and Motivation

Our current HTTP/2 receive window size is 64 Kb, which is too small for many scenarios. It leads to poor throughput, see #43086

We are working on a dynamic window extension algorithm, which is expected to automatically grow the receive window, resulting in good throughput for the vast majority of the users. However, there could be cases when providing manual control over the window size might be a better option. My recommendation is to expose an API proactively for those corner cases.

Examples

The algorithm needs RTT estimation which will be determined by sending PING frames periodically while reading the servers data. Although we are doing our best to make sure that we won't trigger today's server's PING flood detection with their default settings, theoretically it's possible that a strictly configured server may abort the connection. Facing such a case, a user could just disable the dynamic window algorithm (and therefore the PING frames), and set the window size manually.

Another use case: since HTTP2 flow control is hop-by-hop, poorly configured intermediaries may alter the window sizes with H2C in a suboptimal way. I've experienced this by tunneling the connection through a VPN, where some intermediary (firewall?) was intercepting and replacing the WINDOW_UPDATE frames. With that connection, it wasn't possible to reach the desired throughput by extending the receive window with WINDOW_UPDATE's, however setting a large initial window worked.

What about other knobs?

I'm thinking of other parameters like the threshold divisor, or our arbitrarily high connection window increment as implementation details.

Proposed API

public class SocketsHttpHandler
{
    public bool EnableDynamicHttp2StreamWindowSizing { get; set; } // = true;
    public int InitialHttp2StreamWindowSize { get; set; } // = 65535;
}

Usage Examples

var h = new SocketsHttpHandler {
  // Disable the dynamic window algorithm and the periodic PING frames
  EnableDynamicHttp2StreamWindowExtension = false,
  // Set a 16MB receive window manually
  InitialHttp2StreamWindowSize = 16*1024*1024
};

Alternative Designs

[Edited]

  • We considered exposing an AppContext switch / environment variable instad of EnableDynamicHttp2StreamWindowSizing . The disadvantages are: (1) less visible docs (2) less accessible - which means that the user has to do much more facing an issue. Also: (3) can not be fine-tuned per- SocketsHttpHandler. An explicit API feels better for this.
  • We discussed if we should share the API between HTTP2 and a potential HTTP3 flow control fine-tuning mechanism, but decided to keep them separate, see Minimalistic HTTP2 flow control API #53372 (comment)

Risks

None.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions