Acumatica · Bun

Bun vs Node.js Benchmark — A Field Guide

Bun benchmarks faster than Node in many tests, but the headline numbers hide nuance. What matters for a real decision is where the speed holds up and where compatibility decides it instead.

John Kihiu12 min read

Every Bun vs. Node benchmark you'll find online reports different numbers because they're rarely measuring the same thing — HTTP throughput, cold start, package install time, and raw JS execution speed all tell different stories, and Bun doesn't win all four by the same margin. The useful exercise isn't memorizing someone else's numbers; it's understanding which of those four axes actually matters for the workload you're shipping, then benchmarking that specific thing yourself.

Startup time is Bun's clearest win

Bun's process startup — from invocation to first line of JS executing — is consistently and substantially faster than Node's, because Bun is built on JavaScriptCore (Safari's engine) rather than V8, and JavaScriptCore was designed with fast startup as a priority for browser tabs. This matters enormously for CLI tools, serverless functions with cold starts, and CI jobs that spin up a fresh process per test file. It matters much less for a long-running server process that starts once and runs for days.

BASH · A HONEST BENCHMARK SETUP
# Startup time - the axis where Bun wins clearly
hyperfine --warmup 5 'bun run hello.js' 'node hello.js'

# HTTP throughput - closer, and workload-dependent
bun run server.ts &
wrk -t4 -c100 -d30s http://localhost:3000/

node server.js &
wrk -t4 -c100 -d30s http://localhost:3000/

# Package install - Bun's other clear win
rm -rf node_modules bun.lockb package-lock.json
hyperfine --prepare 'rm -rf node_modules' \
  'bun install' 'npm install'

HTTP throughput depends heavily on workload

For raw request-per-second benchmarks on a trivial "hello world" HTTP handler, Bun's built-in HTTP server (built on its own low-level primitives) tends to outperform Node's http module. Once you introduce a real framework — Express on Node vs. Express or Hono on Bun — the gap narrows because framework overhead starts to dominate, and once you add actual work per request (database calls, JSON parsing of real payloads, middleware chains), the runtime difference becomes a smaller fraction of total request latency. The honest takeaway: Bun's raw HTTP layer is faster, but your application code and I/O wait time usually matter more than which runtime executes it.

Package install speed is a bigger everyday win than request throughput

For most teams, the benchmark that actually shows up in daily developer experience is bun install versus npm install — often several times faster thanks to Bun's global cache and parallel install strategy. If your CI spends meaningful time in dependency installation, this is the number worth optimizing for before chasing request-per-second gains.

CPU-bound work is closer than people expect

For pure CPU-bound JavaScript — tight loops, JSON serialization of large objects, string manipulation — V8 (Node) and JavaScriptCore (Bun) trade wins depending on the specific operation, because both are mature, heavily optimized JIT compilers. Neither engine dominates the other across the board on raw compute; the differences that show up in real benchmarks are more often about runtime APIs and I/O handling than about JavaScript execution speed itself.

Don't benchmark against a version of Node you're not actually running

Node's performance has improved significantly across major versions, particularly around V8 upgrades and the newer HTTP parser. A benchmark comparing Bun 1.x against Node 16 tells you nothing about Bun versus the Node 22 LTS most production services actually run. Match the Node version in the comparison to what you'd realistically deploy.

What to actually measure for your service

Run your own benchmark against your own representative workload, under your own load pattern, before making a runtime decision from someone else's chart. For a serverless function billed per invocation, cold start time is probably decisive. For a long-running API service under sustained load, steady-state p99 latency and memory usage under your real traffic shape matter far more than either startup time or a synthetic hello-world benchmark.

Wrapping up

Bun wins decisively on startup time and package install speed, is competitive-to-ahead on HTTP throughput for lightweight handlers, and roughly ties Node on raw CPU-bound JavaScript execution. Pick the axis that matches your actual bottleneck — cold starts, dependency install time, or steady-state request latency — and benchmark that specifically rather than trusting a generic "Bun is 3x faster" headline.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.