Skip to content

parallel requests don't scale #85

@stefan-guggisberg

Description

@stefan-guggisberg

When running parallel requests to the same http2 origin the total time roughly increases linearly with the number of requests.

test.js

const { fetch } = require('fetch-h2');
//const fetch = require('node-fetch-h2');

var args = process.argv.slice(2);
const N = args.length && !isNaN(parseInt(args[0])) ? parseInt(args[0]) : 100;

console.log(`running ${N} paralled requests...`)

const TEST_URL = 'https://httpbin.org/bytes/'; // HTTP2

(async function () {
  // generete array of 'randomized' urls
  const urls = Array.from({ length: N }, () => Math.floor(Math.random() * N)).map((num) => `${TEST_URL}${num}`);

  // establish initial connection
  // (workround for https://github.com/grantila/fetch-h2/issues/39)
  await (await fetch(`${TEST_URL}${N}`)).arrayBuffer();

  const ts0 = Date.now();

  // send requests
  const responses = await Promise.all(urls.map((url) => fetch(url)));

  // read bodies
  await Promise.all(responses.map((resp) => resp.arrayBuffer()));

  const ok = responses.filter((res) => res.ok);
  if (ok.length !== N) {
    console.log(`failed requests: ${N - ok.length}`);
  }

  const ts1 = Date.now();

  console.log(`Elapsed time: ${ts1 - ts0} ms`);
}());

node test.js 10 takes ~1s
node test.js 100 takes ~10s
node test.js 200 takes ~20s

Note that the included workaround for #39 (send an initial blocking request) doesn't have a significant impact on the results.

OTOH, when running the same tests with node-fetch-h2 instead of fetch-h2:

node test.js 10 takes ~200ms
node test.js 100 takes ~300ms
node test.js 200 takes ~500ms

There seems to be a massive bottleneck in fetch-h2 responsible for the poor performance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions