DEV Community

The Hive Collective
The Hive Collective

Posted on • Originally published at thehivecollective.io

Bun for AI agents: where the speed actually shows up (and where it lies)

Bun is fast. The README will tell you 4x on bun install, 3-5x on Bun.serve(), 2x on bun:sqlite. Some of this matters for AI agents. Some of it doesn't.

We've been running production agents on Bun for about 3 months — a mix of Hono-on-Bun HTTP agents and standalone Bun scripts called from Claude Code and OpenClaw. This post is what we'd tell ourselves 3 months ago about where Bun actually helps and where it bites.

Where Bun's speed actually matters for agents

Cold starts on agent scripts

Agents are spawned. A lot. Every Claude Code hook, every npx invocation, every cron-fired worker. Node's startup is ~80-120ms cold; Bun's is ~15-25ms.

For interactive agent loops where the user is waiting on a hook to populate context, that's a noticeable UX difference. The pre-task hook that takes 250ms to do its retrieval feels totally different when the runtime ate 100ms vs 20ms of that budget.

This is the strongest case for Bun in agent workflows. Concrete win.

bun install for ephemeral agent containers

If you spin up containerized agents (Daytona, E2B, Modal, your own ECS task), each cold container does a package install. npm install on a fresh container is 30-90s; bun install is 5-15s. Over thousands of agent runs per day, that's real money.

For Workers / serverless / persistent processes, this doesn't matter — you only install once.

bun:sqlite for local agent memory

If you're building a per-agent local cache (recent tool calls, recently-seen embeddings, scratchpad state), bun:sqlite is genuinely 2x faster than better-sqlite3 on simple selects. It's also zero-install — no native bindings to compile, no Python build chain, just import { Database } from 'bun:sqlite'.

If your agent runs on a Bun runtime AND uses SQLite for state, the math works. If you're on Node, just use better-sqlite3.

Where Bun's "speed" doesn't matter

LLM inference latency

The agent is going to wait 800-4000ms for the LLM to respond. The 50ms of runtime overhead you saved is round-off. Your bottleneck is the model, not the runtime.

This is the comeback to every "Bun is 4x faster" benchmark in an agent context — the agent's wall-clock is dominated by external API calls, not local execution.

Embedding generation when you're hitting OpenAI

Same story. fetch('https://api.openai.com/v1/embeddings') waits 200-600ms. Runtime overhead vanishes.

Anything tool-calling-heavy

A typical agent turn: read user input (1ms) → call LLM (2000ms) → parse tool calls (5ms) → execute tools (varies, often network-bound) → call LLM again (2000ms). Runtime overhead is a rounding error.

Where Bun bites you in production agents

Native bindings ecosystem is incomplete

Anything with a node-gyp native dependency: sharp, canvas, bcrypt (use bcryptjs instead), @grpc/grpc-js for some setups, some Puppeteer/Playwright variants. We hit canvas on an agent that generated thumbnails. Hard switch back to Node for that one service.

The status is improving (Bun 1.2+ closes a lot of gaps) but for agent stacks that touch image processing, gRPC, or older crypto packages, audit before committing.

Some npm packages do runtime-detection that gets Bun wrong

A few packages (looking at undici, some @aws-sdk/* versions, parts of openai's SDK) detect "Node" via process.versions.node and behave differently. Most of the time Bun spoofs this correctly. Sometimes not.

The OpenAI SDK pre-4.50 had a streaming issue on Bun where the response iterator would stall mid-stream. Fixed in their 4.50+ but if you've pinned an older version, you'll see ghosts.

Always pin your OpenAI SDK to a recent version when running on Bun. Same for Anthropic.

Workers / Cloudflare doesn't run Bun

Cloudflare Workers run on V8 isolates. Bun's runtime doesn't apply. If your agents deploy to Cloudflare, the runtime choice is between Node-compat APIs and Workers-native — not Bun.

Same for Vercel Edge, Deno Deploy, and most edge runtimes. Bun lives in long-running server processes (Railway, Fly, Render, your own VPS, Docker).

bun --watch is not tsx --watch

Bun's hot-reload is genuinely fast but it sometimes misses module-graph changes when you move files around. We've had agents go silent in dev because Bun thought the imported file hadn't changed. bun --watch --hot (with explicit --hot) is more reliable.

A pattern that works: Bun on the agent process, Node on the data plane

What we've settled on after 3 months:

  • Agent runtime processes (the things that spawn and die quickly, run hooks, execute tools) → Bun. Cold-start savings compound.
  • API / data plane processes (the long-running HTTP server, the BullMQ workers, the cron jobs that talk to Postgres + Redis + S3) → Node. Ecosystem coverage matters more than the 20ms startup. Also Sentry, OpenTelemetry, Datadog SDKs are all Node-first.
  • Shared library code → written in TypeScript, compiled to ESM with tsc, runs on either. bun:sqlite is the only Bun-specific dep we have; for that one module we have a better-sqlite3 fallback.

If you'd rather not split, the safe default for an agent stack is "Node everywhere, Bun for the agent CLI scripts that need fast cold starts."

The 10-line Bun agent that uses a shared knowledge base

// agent.ts — run with: bun agent.ts
const PROMPT = process.argv.slice(2).join(' ') || 'how do I scale pgvector at 100k rows';
const HIVE = 'https://api.thehivecollective.io';

const hits = await fetch(`${HIVE}/knowledge/query?q=${encodeURIComponent(PROMPT)}&limit=5`).then((r) => r.json());
const context = hits?.data?.results?.map((r: any) => r.content).join('\n---\n') ?? '';

const answer = await callYourLLM([
  { role: 'system', content: 'You are a helpful coding agent. Use the prior findings if relevant.' },
  { role: 'system', content: context },
  { role: 'user', content: PROMPT },
]);

console.log(answer);
Enter fullscreen mode Exit fullscreen mode

That's the whole thing. bun agent.ts "how do I avoid pgvector index bloat" and you have an agent with shared memory across every other agent that's used the same corpus. Cold start ~20ms, query ~250ms warm, LLM call dominates the wall time.

The Hive corpus is free, keyless, public. ~260 entries today, growing daily via an autonomous cron. The dataset is mirrored to a public HF Dataset under CC-BY-SA-4.0 so you have a clone if the API goes down.

TL;DR

Concern Bun helps Bun doesn't help
Agent script cold start ✅ 80ms saved
Ephemeral container install ✅ 25-75s saved
Local SQLite state ✅ 2x faster
LLM API call latency Bottleneck is the model
Embedding API call Bottleneck is OpenAI
Tool-calling loop Bottleneck is the model
Native bindings (sharp, canvas) Often broken or slow
Cloudflare Workers Different runtime entirely

Pick Bun for the agent scripts. Stay on Node for the API and data plane. Don't argue about the rest.


If you've shipped an agent on Bun, I'd love to hear what bit you in production — drop a comment. The corpus prefers concrete findings over takes.

Repos: Maxime8123/thehive-mcp · Maxime8123/thehive-collective

Top comments (0)