Skip to content

Commit ae83331

Browse files
committed
http2: tune control flow defaults
The current defaults are unnecessarily conservative which makes http2 control flow over high latency connections (such as public internet) unbearably slow.
1 parent 2030fd3 commit ae83331

File tree

4 files changed

+16
-5
lines changed

4 files changed

+16
-5
lines changed

doc/api/http2.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3544,10 +3544,10 @@ properties.
35443544
permitted on the `Http2Session` instances. **Default:** `true`.
35453545
* `initialWindowSize` {number} Specifies the _sender's_ initial window size in
35463546
bytes for stream-level flow control. The minimum allowed value is 0. The
3547-
maximum allowed value is 2<sup>32</sup>-1. **Default:** `65535`.
3547+
maximum allowed value is 2<sup>32</sup>-1. **Default:** `262144`.
35483548
* `maxFrameSize` {number} Specifies the size in bytes of the largest frame
35493549
payload. The minimum allowed value is 16,384. The maximum allowed value is
3550-
2<sup>24</sup>-1. **Default:** `16384`.
3550+
2<sup>24</sup>-1. **Default:** `32768`.
35513551
* `maxConcurrentStreams` {number} Specifies the maximum number of concurrent
35523552
streams permitted on an `Http2Session`. There is no default value which
35533553
implies, at least theoretically, 2<sup>32</sup>-1 streams may be open

lib/internal/http2/core.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3302,12 +3302,16 @@ function connectionListener(socket) {
33023302

33033303
socket[kServer] = this;
33043304

3305+
// NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE default is 64KB, but we want to allow more data to be
3306+
// buffered without applying backpressure.
3307+
session.setLocalWindowSize(512 * 1024);
3308+
33053309
this.emit('session', session);
33063310
}
33073311

33083312
function initializeOptions(options) {
33093313
assertIsObject(options, 'options');
3310-
options = { ...options };
3314+
options = { ...getDefaultSettings(), ...options };
33113315
assertIsObject(options.settings, 'options.settings');
33123316
options.settings = { ...options.settings };
33133317

lib/internal/http2/util.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,13 @@ function getDefaultSettings() {
364364
settingsBuffer[IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL] === 1;
365365
}
366366

367+
// NGHTTP2_INITIAL_WINDOW_SIZE default is 64KB, but we want to allow more data to be
368+
// buffered without applying backpressure.
369+
holder.initialWindowSize = MathMax(holder.initialWindowSize, 256 * 1024);
370+
371+
// Default is 16KB.
372+
holder.maxFrameSize = MathMax(32 * 1024, holder.maxFrameSize);
373+
367374
if (settingsBuffer[IDX_SETTINGS_FLAGS + 1]) holder.customSettings = addCustomSettingsToObj();
368375

369376
return holder;

test/parallel/test-http2-binding.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ const settings = http2.getDefaultSettings();
1717
assert.strictEqual(settings.headerTableSize, 4096);
1818
assert.strictEqual(settings.enablePush, true);
1919
assert.strictEqual(settings.maxConcurrentStreams, 4294967295);
20-
assert.strictEqual(settings.initialWindowSize, 65535);
21-
assert.strictEqual(settings.maxFrameSize, 16384);
20+
assert.strictEqual(settings.initialWindowSize, 256 * 1024);
21+
assert.strictEqual(settings.maxFrameSize, 32 * 1024);
2222

2323
assert.strictEqual(binding.nghttp2ErrorString(-517),
2424
'GOAWAY has already been sent');

0 commit comments

Comments
 (0)