cloudflare / cloudflare/workerd
🐛 Bug Report — Runtime APIs: TransformStream with bodies is much slower than other runtimes (10-20x)
- 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
Assessment
This issue has not been assessed yet.