Is Bun so much faster than Node.js?
Tags: javascript, node, bunjs, performance
Published: 2022-07-26 06:29:27

It seems like Bun is the new cool kid in the javascript runtime scenario. Looks very promising and all of that, but, is it that fast?

I will do a set of simple tests, to see if even on a small scale the performance difference is already noticeable. 

Today I will focus only on requests performance and operations per second. 

## Setting up Bun

But first, I'll start installing bun in the bun directory

```
curl https://bun.sh/install | bash
```

And creating a basic response

```
// http.js
export default {
  port: 3000,
  fetch(request) {
    return new Response("Welcome to Bun!");
  },
};
```

## Setting up node
Now I can move on to node. Because I already have Node.js installed I just have to create a basic response as well.

```
const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});
```

Now I'm ready to have fun.

## Http request performance
For the HTTP request performance, I'll test both implementations using Artillery.

Artillery can be installed through npm 
```
npm i artillery
```
And comes with a nice CLI to execute a quick load test.

```
 artillery quick --count 500 --num 100 http://localhost:3000
```

This will run 500 virtual users with 100 requests each.

The results are the following:

| http   | node | bun  |
|------------|----------|-----------|
| http.codes.200        | 50000      | 50000       |
| http.request_rate      | 1585/sec    | 1617/sec     |
| http.requests      | 50000    | 50000     |
| http.responses     | 50000  | 50000    |

| http.response_time   | Node | Bun  |
|------------|----------|-----------|
| min     | 0  | 0    |
| max     | 143  | 73    |
| median     | 32.8  | 22.9    |
| p95     | 63.4  | 36.2    |
| p96     |  100.5 | 50.9   |

| vusers.session_length  | Node | Bun |
|------------|----------|-----------|
| min    | 1835.3 | 1103.1    |
| max    | 4989.2 | 2805.9    |
| median     | 3678.4 | 2566.3    |
| p95     | 4770.6 | 2780    |
| p99     | 4867 | 2780    |

(in milliseconds)

The results are far from the claims in performance from Bun, but still, very solid. In all aspects, Bun stands out as the winner.

## Operations per second

Here I'll do a test of just calculating prime numbers, to see how long it takes for each one.

To test the calculation of prime numbers I will execute a very simple code and make use of `performance.now()` to measure the execution time.

```
(function (maxNumbers = 30000) {
  let start = performance.now();
  let primeNumbers = []
  let numberToCheck = 1;
  while (primeNumbers.length < maxNumbers) {
    if (isPrimeNumber(numberToCheck)) {
      primeNumbers.push(numberToCheck);
    }
    numberToCheck++;
  }

  console.log(performance.now() - start);
})();

function isPrimeNumber(number) {
  for (let i = 2; i < number; i++) {
    if (number % i === 0) return false;
  }
  return true;
}

```

The results for calculating prime numbers are the following (in milliseconds):

| prime numbers | node | bun |
|------------|----------|-----------|
| 100    | 1.035 | 0.618    |
| 500    | 4.5071 | 3.223    |
| 1000     | 9.3060 | 8.680    |
| 5000     | 209.8485 | 198.4309    |
| 10000     | 909.618 | 849.832    |
| 30000     | 9113.5302 | 8559.282    |

This time the results are not that different, but Bun wins again.

Bun is still in beta version, and we should keep that in mind. If at this stage the results already look promising, interesting times will come if the improvement continues along the same lines and, who knows, maybe in some years Bun will find its place on the market.