cloudflare / cloudflare/workerd

🐛 Bug Report — Runtime APIs: TransformStream with bodies is much slower than other runtimes (10-20x)

Open
#5,724 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
8.7k
Forks
739
Avg merge
2d 20h
Merged PRs (30d)
174

Description

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):

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

Ok-ish (135ms):

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

Very slow (694ms):

```js
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:

```js
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");
});
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.