You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using Bun with JSZip (https://www.npmjs.com/package/jszip) to operate on a zip within the context of a Bun.serve or node:http handler yields an enormous performance degradation that is neither present when running the same code with Bun as a CLI script, nor when using Node.js.
In short:
Bun on the CLI + JSZip = fast
Node.js on the CLI + JSZip = fast
Bun + Bun.serve/node:http + JSZip = slow
Node.js + node:http + JSZip = very fast
This was tested using the latest bun alpine container. However, the problem also appears when using an environment in which Bun was installed with curl -fsSL https://bun.sh/install | bash -s "bun-v1.1.8" and I'm pretty sure it also occurs within the context of the official bun lambda runtime (https://github.com/oven-sh/bun/blob/main/packages/bun-lambda/runtime.ts) when deployed to AWS Lambda (I don't have scripts to reproduce the issue in those contexts, but the simple case below should be enough to trigger it. Regardless, it's not specific to alpine).
The issue can be reproduced by using the following script, which can be invoked with either bun index.js to run the standalone version, or by using bun index.js serve, which will start a server on 127.0.0.1:8080 that can be poked with something like curl or wget to trigger the same code from the request handler:
index.js
importhttpfrom"node:http";importJSZipfrom"jszip";constdata="0123456789\n".repeat(2**16);consttest=()=>newJSZip().file("test",data).generateInternalStream({type: "nodebuffer"}).accumulate().then((b)=>`Buffer size: ${b.length}\n`);consthandler=async(req,res)=>res.end(req.method==="HEAD" ? "" : awaittest());if(process.argv[2]==="serve"){constserver=http.createServer(handler).listen(8080,"127.0.0.1");console.log("Server is up");process.on("SIGHUP",()=>server.close());}else{console.log(awaittest());}
Which can be tested using the following hyperfine tests:
docker run --rm -it -v $(pwd):/app -w /app oven/bun:1.1.8-alpine sh -c 'apk add nodejs hyperfine && su bun test.sh'
What is the expected behavior?
I would've expected the code in the request handler to run just as fast as the code in the standalone CLI version, probably faster because of the reduced overhead (since the runtime is already up and running).
What do you see instead?
The Bun request handler (this means both Bun.serve and node:http; the test script uses the latter, but the former performs similarly) appears to run orders of magnitude slower than the CLI version, an issue that isn't present when the code is run with Node.js.
Test results:
test-cli.md
Command
Mean [ms]
Min [ms]
Max [ms]
Relative
bun index.js
53.6 ± 2.6
49.7
59.3
1.00
node index.js
82.9 ± 3.1
77.4
90.1
1.55 ± 0.09
test-server.md
Command
Mean [ms]
Min [ms]
Max [ms]
Relative
wget -qO- http://127.0.0.1:8080/bun
713.3 ± 17.6
688.5
738.7
136.51 ± 15.12
wget -qO- http://127.0.0.1:8080/node
5.2 ± 0.6
3.3
7.3
1.00
Additional information
The larger the zip file, the bigger the slowdown appears to be (~200x for a decently sized ~1MB zip, if I recall correctly). Similar results were achieved when poking the server with cURL, just to eliminate wget as a suspect. I don't have any code prepped to explicitly verify this, but I did run some other tests to confirm JSZip produces the same output in all of these cases/contexts, so it appears to be purely a performance issue.
I'm currently working around this issue by running the affected code in a child process using Bun.spawnSync - it's not pretty, but it works.
The text was updated successfully, but these errors were encountered:
What version of Bun is running?
1.1.8+89d25807f
What platform is your computer?
Linux 6.6.30_1 x86_64 unknown
What steps can reproduce the bug?
Using Bun with JSZip (https://www.npmjs.com/package/jszip) to operate on a zip within the context of a Bun.serve or node:http handler yields an enormous performance degradation that is neither present when running the same code with Bun as a CLI script, nor when using Node.js.
In short:
This was tested using the latest bun alpine container. However, the problem also appears when using an environment in which Bun was installed with
curl -fsSL https://bun.sh/install | bash -s "bun-v1.1.8"
and I'm pretty sure it also occurs within the context of the official bun lambda runtime (https://github.com/oven-sh/bun/blob/main/packages/bun-lambda/runtime.ts) when deployed to AWS Lambda (I don't have scripts to reproduce the issue in those contexts, but the simple case below should be enough to trigger it. Regardless, it's not specific to alpine).The issue can be reproduced by using the following script, which can be invoked with either
bun index.js
to run the standalone version, or by usingbun index.js serve
, which will start a server on127.0.0.1:8080
that can be poked with something like curl or wget to trigger the same code from the request handler:index.js
Which can be tested using the following hyperfine tests:
test.sh
Here's a docker oneliner to run the test script:
What is the expected behavior?
I would've expected the code in the request handler to run just as fast as the code in the standalone CLI version, probably faster because of the reduced overhead (since the runtime is already up and running).
What do you see instead?
The Bun request handler (this means both
Bun.serve
andnode:http
; the test script uses the latter, but the former performs similarly) appears to run orders of magnitude slower than the CLI version, an issue that isn't present when the code is run with Node.js.Test results:
test-cli.md
bun index.js
node index.js
test-server.md
wget -qO- http://127.0.0.1:8080/bun
wget -qO- http://127.0.0.1:8080/node
Additional information
The larger the zip file, the bigger the slowdown appears to be (~200x for a decently sized ~1MB zip, if I recall correctly). Similar results were achieved when poking the server with cURL, just to eliminate wget as a suspect. I don't have any code prepped to explicitly verify this, but I did run some other tests to confirm JSZip produces the same output in all of these cases/contexts, so it appears to be purely a performance issue.
I'm currently working around this issue by running the affected code in a child process using
Bun.spawnSync
- it's not pretty, but it works.The text was updated successfully, but these errors were encountered: