Skip to content

πŸ› Bug Report β€” Runtime APIs: TransformStream with bodies is much slower than other runtimes (10-20x)Β #5724

@mhart

Description

@mhart

Researching the best way to get access to bytes in a request body, and then forward to a destination.

Some examples testing workerd with a 98MiB upload size. In this case the destination will just be the response, but you get similar results forwarding to a subrequest.

Fastest (52.8ms):

export default {
  async fetch(request) {
    return new Response(await request.arrayBuffer());
  }
}

Ok-ish (135ms):

export default {
  async fetch(request) {
    return new Response(request.body);
  }
}

Very slow (694ms):

export default {
  async fetch(request) {
    return new Response(
      request.body.pipeThrough(
        new TransformStream({
          transform(chunk, controller) {
            controller.enqueue(chunk);
          },
        }),
      ),
    );
  }
}

For comparison, the latter TransformStream pattern,

  • on Bun is 33ms
  • on Deno is 46ms
  • on Node.js is 55ms, using this conversion:
import { createServer } from "http";
import { Readable } from "stream";

createServer(async (req, res) => {
  return Readable.fromWeb(
    Readable.toWeb(req).pipeThrough(
      new TransformStream({
        transform(chunk, controller) {
          controller.enqueue(chunk);
        },
      }),
    ),
  )
    .on("error", (err) => {})
    .pipe(res);
}).listen(8787, () => {
  console.log("Listening on http://localhost:8787");
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions