-
-
Notifications
You must be signed in to change notification settings - Fork 427
Description
What version of Elysia is running?
1.4.18
What platform is your computer?
Linux 6.14.0-36-generic x86_64 x86_64
What environment are you using
Bun: 1.3.3
Are you using dynamic mode?
No
What steps can reproduce the bug?
Repo: https://github.com/HuakunShen/js-benchmark.git
README contains all the details. Run ./run-benchmark.sh to run the test.
What is the expected behavior?
I heard that Elysia is performant with bun, but the results is pretty bad with default settings. Although setting AOT = false improved performance, but the default settings is still too bad.
Is AOT enabled by default? shouldn't this improve performance? But I found performance degrade significantly with default settings.
What do you see instead?
AOT compilation causes a 45.7x performance degradation specifically on Bun runtime:
| Configuration | Runtime | Root RPS | JSON RPS | Latency (Root) |
|---|---|---|---|---|
| Elysia 1.4 (default) | Bun | 3,853 | 3,298 | 101.76ms |
| Elysia 1.4 (aot: false) | Bun | 175,951 | 32,275 | 2.27ms |
| Elysia 1.2 (default) | Bun | 64,752 | 18,992 | 6.09ms |
Key Issues:
- AOT causes 45.7x slower performance on Bun (3,853 vs 175,951 RPS)
- The issue is Bun-specific - AOT works fine on Deno (72,178 RPS) and Node.js (33,797 RPS)
- Default settings make Elysia practically unusable on Bun
- Performance contradicts the intended purpose of AOT compilation
Additional information
Environment
- Elysia Version: 1.4.18 (also affects 1.2 when AOT manually enabled)
- Runtime: Bun (latest)
- OS: Linux
- Benchmark Tool: wrk
Reproduction Code
import { Elysia } from 'elysia';
// This uses aot: true by default in 1.4 (broken on Bun)
const app = new Elysia()
.get("/", "Hello Elysia")
.get("/json", () => ({ message: "Hello World", timestamp: Date.now() }));
app.listen(3000);Reproduction Steps
- Create Elysia app with default settings (aot: true)
- Run with Bun:
bun run app.ts - Benchmark:
wrk -t12 -c400 -d10s http://localhost:3000/ - Observe ~3K RPS instead of expected ~150K+ RPS
Working Workaround
import { Elysia } from 'elysia';
// Adding aot: false fixes the issue
const app = new Elysia({ aot: false })
.get("/", "Hello Elysia")
.get("/json", () => ({ message: "Hello World", timestamp: Date.now() }));
app.listen(3000);Performance Comparison with Other Frameworks
| Framework | Runtime | Configuration | RPS |
|---|---|---|---|
| Hono | Bun | - | 237,229 |
| Elysia | Bun | aot: false | 175,951 |
| Elysia | Bun | aot: true (default) | 3,853 |
Root Cause Analysis
The issue appears to be in Elysia's AOT compiler generating code that is incompatible or inefficient with Bun's runtime. The fact that:
- Only Bun is affected (Deno/Node.js work fine)
aot: falseperforms better than supposed optimization- Performance difference is 45x (not marginal)
Suggests a fundamental incompatibility between Elysia's AOT output and Bun's execution environment.
Impact
- Severity: Critical - makes Elysia unusable on Bun with default settings
- User Impact: Silent performance regression (users expect AOT to improve performance)
- Production Risk: Default configuration cannot handle realistic traffic loads
Additional Test Results
The issue was discovered during comprehensive benchmarking across multiple load patterns:
- High load (12 threads, 400 connections): 45.7x regression
- Medium load (4 threads, 50 connections): Similar regression pattern
- Low load (1 thread, 1 connection): Regression persists
This confirms the issue is not load-dependent but fundamental to the AOT compilation process on Bun.
Have you try removing the node_modules and bun.lockb and try again yet?
Yes