Vercel — Bun runtime on Vercel Functions¶
Summary¶
Vercel's 2026-04-21 post announces Bun as a
runtime option for Vercel Functions
in public beta, alongside the pre-existing Node.js
runtime. Bun is selected per-project via a bunVersion field in
vercel.json. Launch-support framework set: Next.js,
Express, Hono, Nitro. Substrate: Bun runs on
Fluid compute with
Active CPU pricing — customers pay
for execution time, not wall-clock I/O-wait time.
The post doubles as Vercel's engineering response to Theo Browne's
cf-vs-vercel-bench
public benchmark. Vercel profiled their infrastructure under the
original benchmark, identified bottlenecks in Node.js's Web Streams
implementation and transform operations ("buffer scanning and data
conversions added measurable CPU cost. Garbage collection also
consumed a significant share of total processing time under heavy
load"), and changed the measurement methodology from TTFB (time-
to-first-byte) to TTLB (time-to-last-byte) — arguing that full
request duration more accurately represents SSR user experience than
first-byte timing. Headline result from re-run: Bun reduced average
latency by 28 % in CPU-bound Next.js rendering workloads compared to
Node.js. React SSR, SvelteKit, and vanilla-JS benchmarks showed similar
cross-runtime performance; the Next.js gap is attributed to Bun's
"optimized handling of web streams and reduced garbage collection
overhead."
Bun is built in Zig; Vercel frames its edge as "optimized I/O and
scheduling that reduce overhead in JavaScript execution and data
handling." Bun's Node-API compatibility is partial — edge-case API
differences "may behave differently" — and cold starts are "slower
than Node.js due to runtime initialization overhead." Node.js is
positioned as default for maximum compatibility + mature ecosystem;
Bun for CPU-intensive / streaming workloads. Both runtimes run native
(no emulation), switching is a config change. Benchmark geography:
1 vCPU / 2 GB on iad1 (us-east-1) with the client VM in the
same AWS region to minimise network variability.
Acknowledges ecosystem-wide wins triggered by the benchmark cycle: Cloudflare optimised V8 GC tuning + proposed a V8-math-flag PR to Node; OpenNext improved Next.js performance across alternative hosts; Vercel itself profiled web-streams bottlenecks.
Key takeaways¶
-
A function platform can expose multiple runtimes as a per-project config axis.
bunVersioninvercel.jsonselects Bun project-wide; absence falls back to Node.js. Canonicalises patterns/multi-runtime-function-platform — the platform-design choice of letting one deployment artefact target N native runtimes, switchable by config without emulation or compatibility shims. Verbatim: "Because Vercel runs native Node.js and Bun runtimes, code runs exactly as it does locally. No emulation or compatibility layers, just full access to each runtime's native capabilities." (Source: this ingest) -
The 28 % Next.js SSR win comes from Web Streams, not from Bun in general. "For Next.js workloads, Bun cut latency by 28 % compared to Node.js. Performance was similar across platforms for React SSR, SvelteKit, and vanilla JavaScript benchmarks. The Next.js performance gains come from Bun's optimized handling of web streams and reduced garbage collection overhead." Profiling narrowed the cause — not Bun's Zig runtime in general, but specifically Node.js Web Streams + transform bottlenecks under Next.js's streaming SSR pattern. Canonicalises concepts/web-streams-as-ssr-bottleneck as the first-class performance concern for streaming-SSR frameworks on Node. Sibling to Cloudflare's same-quarter finding (see sources/2025-10-14-cloudflare-unpacking-cloudflare-workers-cpu-performance-benchmarks) at a different runtime. (Source: this ingest)
-
TTFB understates streaming SSR cost; TTLB captures it. "The original benchmarks measured time-to-first-byte (TTFB), which captures when the server begins sending a response but not the full cost of generating and transmitting it. The benchmarks were updated to measure total request duration (time-to-last-byte). For server rendering workloads, this more accurately represents what users experience, as it includes the complete work of rendering and streaming the response." Canonicalises concepts/ttfb-vs-ttlb-ssr-measurement — TTFB rewards a fast shell flush even if total transfer is slow; TTLB surfaces the per-chunk transform cost streaming SSR actually pays. Measurement choice is load-bearing: the 28 % result is TTLB; a pure-TTFB benchmark would under-report Bun's advantage. (Source: this ingest)
-
Active CPU pricing aligns billing with the CPU-bound axis runtime choice optimises for. "Active CPU pricing means you pay for time spent executing code, not wall-clock time waiting on responses. If your function is waiting for a database query or an API call, you're not being charged for that wait time." Canonicalises concepts/active-cpu-pricing as distinct from AWS-Lambda-style wall-clock (GB-seconds) and Cloudflare-Workers- style CPU-time-only billing. Structurally: makes runtime choice financially legible — faster CPU execution translates directly into lower spend, not indirectly via throughput-per-dollar. On Fluid compute a single instance handles multiple concurrent requests; charging wall-clock would over-bill for I/O wait that parallelises across concurrency. (Source: this ingest)
-
Bun's advantages are concentrated in CPU-intensive / streaming workloads; Node retains compatibility + cold-start wins. Verbatim performance-characteristics table:
| Category | Bun | Node.js |
|---|---|---|
| Performance | Faster for CPU-intensive and streaming workloads | Reliable and consistent across workload types |
| Cold starts | Slower than Node.js due to runtime initialization overhead | Mature and well-optimized |
| Compatibility | Implements Node.js APIs with growing coverage; edge-case differences may exist | Full ecosystem compatibility |
| Ecosystem maturity | Rapidly evolving; smaller community | Stable and widely supported across frameworks and libraries |
| Best use | Performance-critical applications | Default for broad compatibility and production stability |
Canonicalises concepts/runtime-choice-per-workload and patterns/workload-aware-runtime-selection — the design stance that runtime is a per-workload axis (not a platform-wide commitment) traded off on four explicit dimensions: peak performance, cold-start latency, API compatibility, ecosystem maturity. Vercel advises: "Test your dependencies under Bun before migrating production traffic." (Source: this ingest)
-
Platform overhead is negligible in SSR benchmarks — the cost is in the application runtime. "Platform overhead is the time spent in infrastructure code before reaching your application. In these tests, platform overhead accounted for only a small fraction of total request time. Nearly all execution occurred inside the application runtime." Practical consequence: cross-platform SSR benchmark differences reflect runtime + framework choices, not CDN / edge / gateway infrastructure. Matches Cloudflare's same-quarter findings — both vendors independently profiled and concluded the gap lives in Node / framework streams, not in their own platforms. (Source: this ingest)
-
Promised future gain: Bun's
react-dom/serverintegration will further improve React SSR. "We expect the numbers for React SSR will improve further once we integrate Bun's optimizedreact-dom/serverimplementation." Unquantified forward- looking claim. Implies React-SSR parity between runtimes (current benchmark) is not the ceiling — framework-aware runtime integration can close the gap where vanilla React streaming doesn't. (Source: this ingest)
Systems + concepts + patterns surfaced¶
Systems¶
- systems/bun (new) — JavaScript / TypeScript runtime built in Zig; positioned as a Node.js-API-compatible alternative with faster CPU-intensive + streaming workload performance and slower cold starts. Ships its own bundler, test runner, package manager. Launch-ships TypeScript with zero configuration on Vercel.
- systems/vercel-functions (new) — Vercel's general serverless
function primitive (distinct from Vercel Edge Functions at the
V8-isolate altitude). Now multi-runtime: Node.js (default) or Bun
(opt-in via
bunVersion). Runs on Fluid compute with Active CPU pricing. - systems/vercel-fluid-compute (new) — the substrate Vercel Functions runs on: "handles multiple concurrent requests on the same instance." Named architectural difference from per-request isolates or per-request containers. Enables Active CPU pricing by amortising wall-clock I/O wait across concurrent requests.
- systems/hono (new stub) — lightweight web framework with Bun-first support; named in launch-supported framework set alongside Next.js + Express + Nitro.
Concepts¶
- concepts/active-cpu-pricing (new) — billing model where customers pay for active code-execution time, not wall-clock duration. Distinct from AWS-Lambda GB-seconds (wall-clock-based) and from Cloudflare-Workers CPU-time billing (which charges per V8 isolate CPU tick). Structurally coupled to concurrent-request substrates (Fluid compute) — wall-clock billing is wrong when one instance handles N concurrent requests.
- concepts/ttfb-vs-ttlb-ssr-measurement (new) — the benchmarking-methodology distinction between time-to-first-byte and time-to-last-byte as SSR performance metrics. TTFB rewards early shell flush; TTLB captures total streaming + transform cost. Load-bearing for streaming-SSR benchmarks because per-chunk transform work is invisible to TTFB.
- concepts/web-streams-as-ssr-bottleneck (new) — canonical
name for the specific profiling finding: Node.js Web Streams
pipeThrough()chains + transform operations dominate CPU time in streaming SSR workloads due to buffer scanning, data conversions, and garbage collection pressure. Second wiki instance (first: Cloudflare's OpenNext profiling in sources/2025-10-14-cloudflare-unpacking-cloudflare-workers-cpu-performance-benchmarks) at a different runtime. - concepts/runtime-choice-per-workload (new) — the design stance that runtime is a per-workload axis with four explicit trade-off dimensions (peak performance, cold-start latency, API compatibility, ecosystem maturity). Inverts the one-runtime-per- platform historical norm.
Patterns¶
- patterns/multi-runtime-function-platform (new) — the
platform-design pattern of letting one deployment artefact target
multiple native runtimes via config (not emulation). Vercel's
bunVersionfield is the canonical instance; per-project, not per-request. Contrast Cloudflare Workers'nodejs_compatshim (emulation-adjacent) and AWS Lambda's per-function runtime lock. - patterns/workload-aware-runtime-selection (new) — the customer-side pattern of choosing runtime based on the workload's dominant cost axis. Rules of thumb disclosed: CPU-bound / streaming → Bun; mature-ecosystem + cold-start-sensitive → Node.js; mixed portfolio → per-function choice.
Operational numbers disclosed¶
- 28 % average latency reduction for CPU-bound Next.js rendering on Bun vs Node.js (TTLB, ~same region, 1 vCPU / 2 GB).
- Benchmark geometry: 1 vCPU / 2 GB in
iad1(us-east-1); client VM in same AWS region. - Response payload: 5 MB per request (per Cloudflare's 2025-10-14 companion post on the same benchmark — Vercel post doesn't re-disclose).
- Framework coverage at launch: Next.js, Express, Hono, Nitro.
- React SSR / SvelteKit / vanilla JS: "similar across platforms" — no numeric gap disclosed.
- Node.js → V8 flag PR: nodejs/node#60153 (proposed by Cloudflare during the benchmark cycle).
Caveats¶
- Launch-voice product announcement, not a post-mortem or production retrospective. Architecture content ~55 % of the body; remainder is launch framing, marketing CTAs, and ecosystem-thank-you. Passes Tier-3 scope on the substantive profiling + TTFB-vs-TTLB measurement-methodology argument + the four-dimension trade-off table.
- 28 % headline is single-workload, single-region, single-
shape. CPU-bound Next.js rendering on 1 vCPU / 2 GB in
iad1. Bun's advantage on other frameworks not quantified ("similar across platforms"). No tail-latency data (p50 only?), no production-traffic number, no A/B on real customer workload. - Bun's cold-start penalty not quantified. Disclosed qualitatively as "slower than Node.js" — no ms figure, no decile, no comparison to worst-case Lambda cold-start. Material for cold-start-sensitive workloads (<100 ms p99 latency targets, sporadic traffic patterns).
- Public beta — no SLA, no GA date. "We're working closely with the Bun team to bring this capability to production."
- Bun's Node-API compatibility surface not enumerated. "Edge cases may behave differently" — test-dependencies-first advice given but no compatibility matrix disclosed. Unknown which popular Node modules hit divergence.
- Profiling mechanism undisclosed. "We profiled our infrastructure and identified bottlenecks in Node.js web streams implementation" — tool choice (perf? V8 profiler? V8 inspector?), workload shape, representative-sampling strategy all elided.
react-dom/serverintegration timeline unstated.vercel.json bunVersionsyntax not fully walked. Code snippet truncated in post; docs-link provided.- Active CPU pricing numbers undisclosed. Cost per active-CPU- second vs Node on same Fluid substrate not given — can't evaluate TCO against the 28 % latency win.
- Responding to Theo Browne's benchmark is the post's unspoken driver. The benchmark exposed a Vercel vs Cloudflare Workers gap; Vercel's response is Bun (this post) + TTLB measurement pivot + web-streams profiling. Theo's benchmark methodology choices (warmup, payload size, concurrency) shape what the comparisons measure.
- Unsigned. Vercel default attribution.
Source¶
- Original: https://vercel.com/blog/bun-runtime-on-vercel-functions
- Raw markdown:
raw/vercel/2026-04-21-bun-runtime-on-vercel-functions-b3eb3aa8.md
Related¶
- companies/vercel
- systems/bun
- systems/vercel-functions
- systems/vercel-fluid-compute
- systems/nodejs
- systems/nextjs
- systems/hono
- concepts/active-cpu-pricing
- concepts/ttfb-vs-ttlb-ssr-measurement
- concepts/web-streams-as-ssr-bottleneck
- concepts/runtime-choice-per-workload
- concepts/streaming-ssr
- patterns/multi-runtime-function-platform
- patterns/workload-aware-runtime-selection
- sources/2025-10-14-cloudflare-unpacking-cloudflare-workers-cpu-performance-benchmarks — companion benchmark profiling from Cloudflare's side of the same Theo Browne bench.
- sources/2026-02-27-cloudflare-a-better-streams-api-is-possible-for-javascript — Snell's deep-dive on the Node Web Streams performance gap Vercel's profiling also hit.