1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Bun と Node.js で HTTP サーバーを立てて性能を比較してみた

Last updated at Posted at 2025-03-01

はじめに

普段はフリーランスエンジニアをしているRyuと言います!
今回は初めてBunを触った際、あまりにも動作が爆速で驚いたのでNode.jsとの比較をしてみました。

Bun とは

Bun は、最近注目を集めている次世代の JavaScript ランタイムです。Node.js や Deno と同様にサーバーサイドの JavaScript 実行環境を提供しますが、高速な起動や統合ツール群(バンドラー、トランスパイラー、パッケージマネージャ)が特徴です。Bun のコアは Zig  という言語で実装されており、パフォーマンス面での優位性を発揮しています。

Bun のここがすごい

高速性

Node.js と比較して、サーバの起動時間やリクエスト処理速度が数倍高速です。

統合ツール群

Node.js 単体ではランタイムのみを提供し、パッケージ管理(npm や Yarn)、バンドラー(webpack、Rollup など)、トランスパイラー(Babel など)は別途導入する必要がありますが、Bun はそれらすべて Bun の中にまとまって提供されます。

TypeScript 対応

最新の ECMAScript 機能をサポートしており、TypeScript もネイティブに扱えます。TypeScript をトランスパイルなしで直接実行可能なので Node.js では ts-node などを追加でインストールする必要がありますが、Bun ならその手間が不要です。

ホットリロード対応

bun dev コマンドを使って立ち上げた開発サーバに、コードの変更をリアルタイムで反映できます。

テストランナー実装

Node.js を使用する場合は Jest のような外部のテストフレームワークを使ってテストしますが、Bun 独自のテストランナーを備えているため高速かつシンプルにテストの実行が可能

用語解説

ランタイム

ランタイムとは、プログラムが「実行」される環境のことです。
たとえば、JavaScript のランタイムとしては、ブラウザ環境が挙げられますが、サーバサイドでは Node.js や Bun などがこれに該当します。これらは、JavaScript コードを実行するために、独自の API やシステムリソース管理の仕組みを備えています。

バンドラー

バンドラーとは、複数の JavaScript モジュールやその他のリソース(CSS、画像など)を解析し、1 つまたは少数のファイルにまとめるツールのことです。

トランスパイル

ソースコードを解析し、構文や機能を理解した上で、目的の環境に適したコードに再生成することです。例えば、型付けされた TypeScript コードを、ブラウザや Node.js で実行可能な JavaScript に変換すること。

前準備

Bun と Node.js の比較をするために、まずは Docker で Bun と Node.js のコンテナを作成していきます。

Bun の Dockerfile

FROM oven/bun:latest

WORKDIR /app

COPY package.json .
COPY server.ts .

RUN bun install

EXPOSE 3001

CMD ["bun", "run", "server.ts"]

Node.js の Dockerfile

FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
COPY tsconfig.json ./
COPY server.ts ./

RUN npm install

EXPOSE 3002

CMD ["npm", "start"]

docker-compose.yml

version: "3"

services:
  bun-server:
    build:
      context: ./bun-server
      dockerfile: Dockerfile
    ports:
      - "3001:3001"
    container_name: bun-server

  node-server:
    build:
      context: ./node-server
      dockerfile: Dockerfile
    ports:
      - "3002:3002"
    container_name: node-server

Bun で HTTP サーバーを作成

では早速 Bun を使用して HTTP サーバーを立てていきましょう。

// server.ts
import { Server } from "bun";

const server: Server = Bun.serve({
  port: 3001,
  fetch(request: Request): Response {
    return new Response("Hello from Bun Server!");
  },
});

console.log(`Bun server listening on ${server.url}`);

非常にシンプルな記述で HTTP サーバーを立てることができました。

Node.js で HTTP サーバーを立ててみる

では次は Node.js を使用して HTTP サーバーを立てていきましょう。

// server.ts
import { createServer, IncomingMessage, ServerResponse } from "http";

const server = createServer((req: IncomingMessage, res: ServerResponse) => {
  res.statusCode = 200;
  res.setHeader("Content-Type", "text/plain");
  res.end("Hello from Node.js Server!");
});

const PORT: number = 3002;
server.listen(PORT, () => {
  console.log(`Node.js server listening on port ${PORT}`);
});

Bun と Node.js のパフォーマンス比較

コンテナの立ち上げ

まずは上記のコードをもとにコンテナを立てて HTTP サーバーを立ててみましょう。

docker-compose up -d

ブラウザでhttp://localhost:3001http://localhost:3002にアクセスして以下のように各サーバーが立ち上がったら成功です。

↓Bun サーバー
20250301-01.png

↓Node.js サーバー
20250301-02.png

ベンチマークテストツール

今回ベンチマークテストツールとしてautocannonを使用します。
autocannonは Node.js の HTTP サーバーのパフォーマンスを計測するためのツールです。(Bun にも使えます)

npm install -g autocannon

ベンチマークテスト

Bun サーバーと Node.js サーバーのベンチマークテストを実行してみましょう。

autocannon -c 100 -d 30 http://localhost:3001
autocannon -c 100 -d 30 http://localhost:3002

これは各対象の HTTP サーバーに 100 個の同時接続して 30 秒間リクエストを送信してパフォーマンスを計測するコマンドです。

結果を見てみましょう。

PS C:\project\Bun> autocannon -c 100 -d 30 localhost:3001
Running 30s test @ http://localhost:3001
100 connections


┌─────────┬──────┬───────┬───────┬───────┬──────────┬─────────┬────────┐
│ Stat    │ 2.5% │ 50%   │ 97.5% │ 99%   │ Avg      │ Stdev   │ Max    │
├─────────┼──────┼───────┼───────┼───────┼──────────┼─────────┼────────┤
│ Latency │ 8 ms │ 11 ms │ 17 ms │ 19 ms │ 11.76 ms │ 4.18 ms │ 251 ms │
└─────────┴──────┴───────┴───────┴───────┴──────────┴─────────┴────────┘
┌───────────┬────────┬────────┬─────────┬─────────┬─────────┬─────────┬────────┐
│ Stat      │ 1%     │ 2.5%   │ 50%     │ 97.5%   │ Avg     │ Stdev   │ Min    │
├───────────┼────────┼────────┼─────────┼─────────┼─────────┼─────────┼────────┤
│ Req/Sec   │ 5,431  │ 5,431  │ 8,191   │ 9,095   │ 8,201.8 │ 659.22  │ 5,431  │
├───────────┼────────┼────────┼─────────┼─────────┼─────────┼─────────┼────────┤
│ Bytes/Sec │ 750 kB │ 750 kB │ 1.13 MB │ 1.25 MB │ 1.13 MB │ 90.9 kB │ 749 kB │
└───────────┴────────┴────────┴─────────┴─────────┴─────────┴─────────┴────────┘

Req/Bytes counts sampled once per second.
# of samples: 30

246k requests in 30.23s, 34 MB read
PS C:\project\Bun>
PS C:\project\Bun>
PS C:\project\Bun> autocannon -c 100 -d 30 localhost:3002
Running 30s test @ http://localhost:3002
100 connections


┌─────────┬───────┬───────┬───────┬───────┬──────────┬─────────┬────────┐
│ Stat    │ 2.5%  │ 50%   │ 97.5% │ 99%   │ Avg      │ Stdev   │ Max    │
├─────────┼───────┼───────┼───────┼───────┼──────────┼─────────┼────────┤
│ Latency │ 11 ms │ 15 ms │ 30 ms │ 33 ms │ 15.95 ms │ 5.47 ms │ 158 ms │
└─────────┴───────┴───────┴───────┴───────┴──────────┴─────────┴────────┘
┌───────────┬────────┬────────┬─────────┬────────┬──────────┬────────┬────────┐
│ Stat      │ 1%     │ 2.5%   │ 50%     │ 97.5%  │ Avg      │ Stdev  │ Min    │
├───────────┼────────┼────────┼─────────┼────────┼──────────┼────────┼────────┤
│ Req/Sec   │ 3,553  │ 3,553  │ 6,235   │ 6,847  │ 6,080.77 │ 577.53 │ 3,552  │
├───────────┼────────┼────────┼─────────┼────────┼──────────┼────────┼────────┤
│ Bytes/Sec │ 622 kB │ 622 kB │ 1.09 MB │ 1.2 MB │ 1.06 MB  │ 101 kB │ 622 kB │
└───────────┴────────┴────────┴─────────┴────────┴──────────┴────────┴────────┘

Req/Bytes counts sampled once per second.
# of samples: 30

183k requests in 30.06s, 31.9 MB read

こちら上記結果をChatGPTくんに要約してもらったものです。

レイテンシー(応答時間):
3001(Bun): 平均11.76ms
3002(Node.js): 平均15.95ms
→ 3001の方が約35%速い

毎秒リクエスト処理数(Req/Sec):
3001(Bun): 平均8,201.8
3002(Node.js): 平均6,080.77
→ 3001の方が約35%多くのリクエストを処理

30秒間の総リクエスト数:
3001(Bun): 246,000リクエスト
3002(Node.js): 183,000リクエスト
→ 3001の方が約63,000リクエスト多く処理

こんな単純な処理を返すサーバーでもBunの方がNode.jsよりも高いパフォーマンスを発揮していることがわかりますね。

まとめ

BunはNode.jsよりも高速で、シンプルな記述でHTTPサーバーを立てることができます。
皆さんもぜひBunを使ってみてください!

もし記事に追記した方がいいことや誤り等ありましたらご連絡ください!

個人ブログでも記事投稿しているので暇な時にでも覗いてやってくださいm(._.)m
https://ryu-engineer.com/

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?