bun
                                
                                
                                
                                    bun copied to clipboard
                            
                            
                            
                        Implement `node:cluster` module
What version of Bun is running?
0.5.7
What platform is your computer?
Linux 6.2.0-76060200-generic x86_64 x86_64
What steps can reproduce the bug?
bun i rate-limiter-flexible
import { RateLimiterMemory } from "rate-limiter-flexible";
const rateLimiter = new RateLimiterMemory({ points: 5, duration: 120, });
What is the expected behavior?
No response
What do you see instead?
No response
Additional information
No response
We haven't implemented the Node.js cluster module yet.
Is there currently any other way to do multiprocessing/multithreading with bun? This seems like it should be a very high priority item to support.
+1 on this. The lack of node:cluster implementation is probably the main reason we are not switching to Bun right now.
+1 on this. The lack of
node:clusterimplementation is probably the main reason we are not switching to Bun right now. Same here i am shifting back to node since i get know thatnode:clusteris not available yet
I got indeed:
error: Could not resolve Node.js builtin: "cluster". To use Node.js builtins, set target to 'node' or 'bun'
const cluster = require('cluster')
I was very surprised to see this error. EDIT: I know cluster is not yet implemented. But then don't call it bun 1.0 yet.
I ran bun --bun run dev to run my nextJS app. And I got this exact error.
Well, node:cluster isn't implemented yet, so that's why you're seeing the error.
+1
For now (Bun v.1.0.3), I can imitate the behavior of the node:cluster in Bun to spawn as many server instances as the number of CPU cores, using this script.
spawn.ts
import os from "node:os";
const numCPUs = os.cpus().length;
for (let i = 0; i < numCPUs; i++) {
  Bun.spawn(["bun", "index.ts"], {
    stdio: ["inherit", "inherit", "inherit"],
    env: { ...process.env },
  });
}
index.ts
Bun.serve({
  port: 8080,
  reusePort: true, // allow Bun server instances to use same port 
  fetch(req: Request) {
    // ...
run bun spawn.ts
@masfahru,
I performed the test and observed that the process ID remains the same every time I access the endpoint and print it. It appears that the access point is not redistributing properly.
 if (process.pid) {
            console.log(process.pid);
 }
index.ts
const server = Bun.serve({
    port: 3000,
    // @ts-ignore
    reusePort: true, // allow Bun server instances to use same port
    fetch(request) {
        if (process.pid) {
            console.log(process.pid);
        }
        return new Response("Welcome to Bun!");
    },
});
console.log(`Listening on localhost:${server.port}`);
cluster.ts
import os from "node:os";
const numCPUs = os.cpus().length;
for (let i = 0; i < numCPUs; i++) {
    Bun.spawn(["bun", "index.ts"], {
        stdio: ["inherit", "inherit", "inherit"],
        env: { ...process.env },
    });
}
                                    
                                    
                                    
                                
@calebeaires
SO_REUSEPORT is a builtin way to do load balancing, but it only really works properly on Linux.
Sorry, I don't know how load balancing works in Bun. To fulfill my curiosity about Bun server performance, I have tested the script in the TechEmpower Framework Benchmark, and the result is amazing. Bun is able to serve up to 2.7M requests per second for plain text test.
@masfahru, you're right. I've tested in a linux machine and works like a charm.
@calebeaires Would you mind sharing the details on what hardware/setup was used to achieve those numbers?
On M1 Mac OS 8 cores, it does not work. On linux, Ubuntu 22, 2 cores I could get a good result. Sending concurrent requests to Bun server that console log the process.id numbers, we get different results.
+1 on this. The lack of
node:clusterimplementation is probably the main reason we are not switching to Bun right now.
THIS!
没有像Nodejs那样的多进程/线程,我觉得这应该是一个优先级很高的问题,并且应该写到示例文档里,我认为应该如此,毕竟这是一个性能相关的问题。我看了一下回复列举的代码,等会试试看有没有效果。
Google Machine Translate -> There are no multi-processes/threads like Nodejs. I think this should be a high priority issue and should be written into the sample documentation. I think it should be so. After all, this is a performance related issue. I took a look at the code listed in the reply and will try it later to see if it has any effect.
+1 I Can't fully convert my node apps to bun without this feature.
I do wait for this feature in order to switch to bun on all my node apps.
Can we please keep this thread productive, such as discussing potential implementations?
I'm looking forward to seeing this feature implemented in Bun.
+1 for this.
I am also recommend implementing cluster_thread module which is genuinely a good starting point for creating clusters of threads like clusters of processes in node.js. Currently a multi-threading option is a little buggy. There is no random round robin as well in Windows due to absence of file descriptor module [presumed - check] in windows environment.
This is the Node.js Suggestion recommendation. https://github.com/nodejs/node/issues/48350
@masfahru,
I performed the test and observed that the process ID remains the same every time I access the endpoint and print it. It appears that the access point is not redistributing properly.
if (process.pid) { console.log(process.pid); }index.ts
const server = Bun.serve({ port: 3000, // @ts-ignore reusePort: true, // allow Bun server instances to use same port fetch(request) { if (process.pid) { console.log(process.pid); } return new Response("Welcome to Bun!"); }, }); console.log(`Listening on localhost:${server.port}`);cluster.ts
import os from "node:os"; const numCPUs = os.cpus().length; for (let i = 0; i < numCPUs; i++) { Bun.spawn(["bun", "index.ts"], { stdio: ["inherit", "inherit", "inherit"], env: { ...process.env }, }); }
Actually the feature for Bun.serve to allow port reuse (reusePort:true) and simple Bun.spawn of a number of processes works a treat. We have refactored a node:cluster websocket application using this simple approach and found it to be quite straightforward (on Linux at least), sharing both 443 and 80 (hsts). The ipc comms makes it a pretty simple drop in replacement with some simple rewrites. Subsequent websocket connections are load balanced by the OS in round robin. Still need to load test but functional.
We haven't implemented the Node.js
clustermodule yet.
Is there a timeline on this? Would love to have this feature!
Just came to this thread to tell, all the benchmark blogs n videos are comparing nodejs (clustered), Go (which is natively clustered) vs Bun. Though Bun outperform node on single process mode but its really not good for general sentiment build up. It'd be really hard to educate the masses on fair grounds of comparison. If we could implement clustered mode that would be really great.
I hope this feature release soon.
Just came to this thread to tell, all the benchmark blogs n videos are comparing nodejs (clustered), Go (which is natively clustered) vs Bun.
Not really https://web-frameworks-benchmark.netlify.app/result?l=javascript is comparing node vs bun on with clustering for both of them. Clustering could be done, but it depends ... It could be useless, with some architecture, to have clustering mode
So in my opinion having used node:cluster for many years (and the cluster module pre integration), the ability to reuse sockets in the Bun.serve implementation pretty much removes the need for node:cluster support in Bun for some of the use cases. The IPC channel support is identical syntax, and things like http/s and websocket server port sharing just work out of the box on Linux. Spawn separate workers and reuse the ports. Reach out if you need any guidance but we've pretty much deprecated the need for the cluster capability with what Bun already has implemented. Cheers Rob
So in my opinion having used node:cluster for many years (and the cluster module pre integration), the ability to reuse sockets in the Bun.serve implementation pretty much removes the need for node:cluster support in Bun for most of the use cases. The IPC channel support is identical syntax, and things like http/s and websocket server port sharing just work out of the box on Linux. Spawn separate workers and reuse the ports. Reach out if you need any guidance but we've pretty much deprecated the need for the cluster capability with what Bun already has implemented. Cheers Rob
What if I want to have multiple instances of smtp-server running on port 25? Only other option would be nginx, but that comes with its own set of issues.
So in my opinion having used node:cluster for many years (and the cluster module pre integration), the ability to reuse sockets in the Bun.serve implementation pretty much removes the need for node:cluster support in Bun for most of the use cases. The IPC channel support is identical syntax, and things like http/s and websocket server port sharing just work out of the box on Linux. Spawn separate workers and reuse the ports. Reach out if you need any guidance but we've pretty much deprecated the need for the cluster capability with what Bun already has implemented. Cheers Rob
What if I want to have multiple instances of smtp-server running on port 25? Only other option would be nginx, but that comes with its own set of issues.
Understood, and yes you'd need to handle that externally (nginx, possibly pm2 would be another option but not sure) Another approach we have done in the nodejs world is have a single process handle the raw port, then workers doing what's needed. I've modified my comment to say some rather than most
+1 on this. The lack of
node:clusterimplementation is probably the main reason we are not switching to Bun right now.
+1
So in my opinion having used node:cluster for many years (and the cluster module pre integration), the ability to reuse sockets in the Bun.serve implementation pretty much removes the need for node:cluster support in Bun for some of the use cases. The IPC channel support is identical syntax, and things like http/s and websocket server port sharing just work out of the box on Linux. Spawn separate workers and reuse the ports. Reach out if you need any guidance but we've pretty much deprecated the need for the cluster capability with what Bun already has implemented. Cheers Rob
The use-case would still be to reinforce Bun's statement of being a "drop-in" replacement for Node, since most of the functionality that entails the cluster module is apparently already implemented, I hope some of the code can be reused for a node:cluster module (mock?).