惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
Blog — PlanetScale
Blog — PlanetScale
月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
爱范儿
爱范儿
量子位
博客园 - 聂微东
Engineering at Meta
Engineering at Meta
WordPress大学
WordPress大学
GbyAI
GbyAI
MyScale Blog
MyScale Blog
IT之家
IT之家
P
Proofpoint News Feed
M
MIT News - Artificial intelligence
The Cloudflare Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Hugging Face - Blog
Hugging Face - Blog
The Register - Security
The Register - Security
Microsoft Security Blog
Microsoft Security Blog
博客园_首页
MongoDB | Blog
MongoDB | Blog
F
Fortinet All Blogs
博客园 - 三生石上(FineUI控件)
Y
Y Combinator Blog
雷峰网
雷峰网
V
Visual Studio Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Last Week in AI
Last Week in AI
博客园 - 叶小钗
D
DataBreaches.Net
B
Blog
B
Blog RSS Feed
大猫的无限游戏
大猫的无限游戏
aimingoo的专栏
aimingoo的专栏
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The GitHub Blog
The GitHub Blog
云风的 BLOG
云风的 BLOG
Recent Announcements
Recent Announcements
阮一峰的网络日志
阮一峰的网络日志
小众软件
小众软件
腾讯CDC
T
Threat Research - Cisco Blogs
SecWiki News
SecWiki News
Martin Fowler
Martin Fowler
D
Docker
Cisco Talos Blog
Cisco Talos Blog
T
Tenable Blog
Webroot Blog
Webroot Blog
宝玉的分享
宝玉的分享

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
NodeJS vs Bun vs Go
Aditya Sriva · 2026-05-25 · via DEV Community

Mon 25 May 2026,

Premise:
I came across a video discussing the new Bun.image. How the developers at Bun gave it native Image support that was 'Blazing fast'.
This lead me to wonder just how much more performant bun was at regular http server as compared to NodeJS.

I am a software developer with 4 years of experience mainly at creating Node services. I feel safe to say that I have good understanding of Node's architecture, its limits and production capabilities when handling high throughput network I/O

However, I am still very new to Bun, So, I decided to make this simple benchmark, where I run a simple http server in Node, Bun and GO.

GO is just a control here. Given the bare-metal nature of Go, I thought it would be a good control, and help me understand how much bloat do Node and bun carry, within their V8/JSC and libuv/zig.

The Cloud-Native Battle Royale: Node vs. Bun vs. Go

From Localhost to Cloud Reality—Tracking the Bottlenecks Step-by-Step.

Its easy to confuse localhost performance to that of hosted environments. You run a quick hello-world benchmark on localhost, watch Bun or Node spit out massive numbers inside your laptop's RAM, and declare your favorite runtime the undisputed king of speed.

But localhost is a lie. Inside RAM, you aren't testing software architecture—you're testing how fast your CPU can copy strings across a local memory bus.

To uncover the some of the production truth, I will be comparing three popular backend stacks, sandboxed them strictly inside Docker, and ran them through controlled configs:

from local memory buses,
over an encrypted Wi-Fi mesh network,
and finally unchained onto enterprise-grade Linux cloud hardware.


Node, Bun and Go all will be running default out of the box http servers. They will handle incoming traffic on /json and return a simple json response.
{ message: 'Hello from ${Node/ Bun/ Go}' }

Phase 1: The Localhost Baseline

Our journey started on a local Windows development machine. We pinned our containers to a single core, scaled up to 4 cores using standard single-threaded configurations, and finally introduced clustering.

Phase 1 Ledger: Local Memory Performance

Benchmark Phase Node.js Bun Go (Optimized Raw Bytes)
1 CPU Core Baseline ~14,000 RPS ~28,000 RPS ~29,000 RPS
4 CPU Cores (No Cluster) ~16,000 RPS (Stuck) ~30,000 RPS (Stuck) ~115,000 RPS 🚀
4 CPU Cores (Clustered) ~110,000 RPS ~170,000 RPS 🏆 N/A (Go handles natively)

The Localhost Plot Twist

  • The Single-Threaded Wall: In the 4-core run with no clustering, Node and Bun completely stalled. Because JavaScript is single-threaded, they could only ever utilize 100% of a single core, leaving the other 3 cores sitting completely idle. Meanwhile, Go's native scheduler effortlessly utilized the available hardware, scaling to 115,000 RPS out of the box.
  • The Clustered Beast: The moment we turned on Node's cluster module and spawned 4 parallel instances of Bun, the JavaScript engines woke up. Bun rocketed to a staggering 170,000 RPS over local memory. On paper, it looked completely untouchable.

Phase 2: The Physical Reality Check (Over Tailscale)

Then came the first massive architectural shift. We forced the packets to leave the cozy confines of local laptop RAM and cross a real, physical network layer. I hooked up my MacBook over Tailscale virtual private mesh network, sending requests over the airwaves via a local Wi-Fi adapter.

The moment traffic hit the air, the 170,000 RPS powerhouses slammed headfirst into a concrete wall.

Phase 2 Ledger: The Encrypted Airwaves (4 Cores)

Metric Node.js (4 Workers) Bun (4 Instances) Go (Optimized Raw Bytes)
Throughput (RPS) 7,954 RPS 12,519 RPS 12,873 RPS 🏆
Average Latency 26.79 ms 16.49 ms 15.69 ms 🏆
Max Outlier Latency 864.53 ms ⚠️ 163.24 ms 152.21 ms 🏆
Data Transfer Rate 1.62 MB/s 1.76 MB/s 1.67 MB/s

Shifting from CPU to Network-Bound I/O

The engines were no longer fighting each other; they were all waiting in line for the physical Wi-Fi card to modulate radio waves and process encrypted WireGuard UDP wrappers.

  • Go Reclaimed the Crown: Because Go's native network poller integrates directly with the OS kernel stack, it handled network jitter with absolute stability, locking down the lowest average and outlier latencies.
  • Node.js Crumbled Under Jitter: Node's master process struggled to distribute incoming packets with uneven arrival times to its workers, causing outlier latencies to skyrocket to a near-fatal 864ms.

Important to note that my PC has a very basic tenda u10 wifi usb adapter. It only supports wifi3 and was very likely the bottleneck.

This highlighted that often, systems are network bottlenecked, and its unfair to continue testing with my current hardware and environment. So I decided to isolate the tests from my hardware limitations by hosting them on digital ocean droplets.


Phase 3: Unchained on the Cloud

To find out the absolute ceiling of our code without network noise or local virtualization layers, I moved the experiment onto enterprise-grade Linux cloud hardware (DigitalOcean Shared Droplets over a 10 Gbps data center backplane).

Deployed a target server VM and a separate attacker VM inside the same data center switch, isolated their resource environments natively via Docker runtime flags, and re-ran the gauntlet.

Step 3.1: Running the Baseline Cloud Sandboxes (1 CPU)

To run the isolated 1-Core tests on the target host, we spun up each server container using a strict resource quota constraint:

# Target VM - Launching Single Core Baselines
docker run --rm --cpus="1" -m="512m" -p 3000:3000 --name cloud-bench node-bench
docker run --rm --cpus="1" -m="512m" -p 3000:3000 --name cloud-bench bun-bench
docker run --rm --cpus="1" -m="512m" -p 3000:3000 --name cloud-bench go-bench

Enter fullscreen mode Exit fullscreen mode

Phase 3 Ledger: Cloud-Native 1-CPU Baseline

Metric Node.js (1 Core) Go (1 Core - Optimized) Bun (1 Core)
Throughput (RPS) 11,705 RPS 13,935 RPS 25,444 RPS 🏆
Average Latency 29.13 ms 22.83 ms 7.89 ms 🏆
Max Outlier Latency 2,000.00 ms ⚠️ 135.97 ms 93.27 ms
Failed Requests 60 Timeouts ⚠️ 0 0

On a single cloud core, Node’s V8 engine choked trying to handle 11k packets per second alongside its own internal event loop bookkeeping, dropping 60 socket timeouts. Bun's ultra-lightweight Zig event loop effortlessly handled the single-core constraint, smashing Go by double the speed.


Phase 4: Full Multi-Core Cloud Concurrency

Finally, we opened the valves completely. I scaled the target configurations to a 4 CPU Core allocation using clustered variants for the JavaScript runtimes to allow multi-threaded scheduling:

# Target VM - Launching Multi-Core Clusters
docker run --rm --cpus="4" -m="512m" -p 3000:3000 --name cloud-bench node-bench-c
docker run --rm --cpus="4" -m="512m" -p 3000:3000 --name cloud-bench bun-bench-c
docker run --rm --cpus="4" -m="512m" -p 3000:3000 --name cloud-bench go-bench

Enter fullscreen mode Exit fullscreen mode

The Automation Attack Script

To collect clean, zero-friction metrics, the Attacker VM offloaded the load generator inside an Alpine container using an optimized execution thread limit:

# Attacker VM - The Native wrk Attack Command
docker run --rm alpine sh -c "apk add --no-cache wrk && wrk -t2 -c200 -d30s http://159.65.6.89:3000/json"

Enter fullscreen mode Exit fullscreen mode

Phase 4 Ledger: Cloud-Native 4-CPU Maximum Performance

Metric Node.js Cluster (4 Cores) Go Optimized (4 Cores) Bun Cluster (4 Cores)
Throughput (RPS) 31,025 RPS 37,617 RPS 53,446 RPS 🏆
Total Requests (30s) 933,074 1,130,171 1,605,818
Average Latency 8.62 ms 5.79 ms 4.04 ms 🏆
Worst-Case Spike 641.25 ms ⚠️ 218.91 ms 76.54 ms 🏆
Peak CPU (Docker Stats) >400% (Thrashing) 340% (Highly Efficient) 🏆 383% (Perfect Scaling)

The Architectural Post-Mortem

1. Bun is the New Raw I/O King (53,446 RPS)

Bun scaled almost perfectly linearly across the 4 vCPUs, hitting 383% CPU utilization in docker stats. By dropping V8's weight and building its HTTP server straight into Zig, Bun handles native OS socket interactions with almost zero orchestration loss. It spent practically zero time handling internal lock contention, keeping its average latency at a jaw-dropping 4.04ms under massive load.

2. Go is an Infrastructure Masterpiece (37,617 RPS)

Go generated elite throughput while using only 340% CPU, leaving an entire 60% of a physical core free for the OS to breathe.

We achieved this by bypassing the standard routing tree and writing pre-rendered raw bytes directly to the network buffer—completely eliminating runtime reflection and heap allocations. Go's native user-space goroutine scheduler managed the multi-core scaling in a single process, proving why it remains the gold standard for resource efficiency and predictability.

3. Node.js Suffers From the "Cluster Tax" (31,025 RPS)

Node bounced back, but it ran hot—constantly thrashing above 400% CPU utilization. Because Node requires separate cloned V8 processes communicating via Inter-Process Communication (IPC) to pass socket descriptors, the CPU burns valuable clock cycles handling internal kernel-space locking and thread synchronization instead of serving requests.


The Production Takeaway

  • Bun is no longer just a fast local test runner; its cloud-native I/O layer is a legitimate production speed-demon.
  • Go remains the rock-solid king of predictable infrastructure, giving you massive throughput with flatlined resource consumption and unparalleled stability.
  • Node.js works, but under extreme enterprise concurrency, its legacy multi-process architecture forces your hardware to work significantly harder to produce less output.

Code snippets

Bun - Clustered

Bun.serve({
  port: 3000,
  reusePort: true, // Key flag: allows multiple processes to bind to port 3000
  fetch(request) {
    const url = new URL(request.url);
    if (request.method === 'GET' && url.pathname === '/json') {
      return new Response(JSON.stringify({ message: "Hello from Clustered Bun!" }), {
        headers: { 'Content-Type': 'application/json' },
      });
    }
    return new Response("Not Found", { status: 404 });
  },
});

Enter fullscreen mode Exit fullscreen mode

Node - Clustered

const cluster = require('cluster');
const http = require('http');
const numCPUs = 4; // Matching our --cpus="4" flag

if (cluster.isMaster) {
  // Fork workers for each core
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker) => {
    cluster.fork(); // Simple failover
  });
} else {
  // Workers share the TCP connection
  http.createServer((req, res) => {
    if (req.method === 'GET' && req.url === '/json') {
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ message: "Hello from Clustered Node!" }));
    } else {
      res.writeHead(404);
      res.end();
    }
  }).listen(3000);
}

Enter fullscreen mode Exit fullscreen mode

Go

package main

import (
    "fmt"
    "net/http"
)

// Pre-render the exact JSON byte slice at startup to completely eliminate allocation/reflection
var jsonResponse = []byte(`{"message":"Hello from Go!"}`)

func jsonHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodGet {
        w.WriteHeader(http.StatusMethodNotAllowed)
        return
    }

    // Set headers and write raw bytes directly to the network buffer
    w.Header().Set("Content-Type", "application/json")
    w.Write(jsonResponse)
}

func main() {
    // Disable internal tracking features we don't need for a barebones benchmark
    server := &http.Server{
        Addr:    ":3000",
        Handler: http.HandlerFunc(jsonHandler),
    }

    fmt.Println("Optimized Go running on port 3000")
    server.ListenAndServe()
}

Enter fullscreen mode Exit fullscreen mode