Investigating Potential Memory Leaks in Bun's Zero‑Copy HTTP Server
0 reputation · 10 Oct 2024, 01:16 UTC
0 reputation · 10 Oct 2024, 01:16 UTC
Goal: determine whether Bun's zero‑copy HTTP server reuses buffers in a way that can cause memory leaks under sustained high concurrency.
Constraints: use the latest stable Bun release, run a simple Bun.serve() endpoint that echoes request bodies, no custom buffer pools, on a Linux system with default TCP stack. Monitor RSS via top or htop while generating traffic with wrk.
Uncertainty: the runtime documentation states that buffers are reused to reduce GC pressure, but it does not detail the lifecycle of these buffers when requests finish or when connections close.
Questions:
Bun.serve() HTTP server, and can it lead to memory leaks when handling many concurrent connections?34775 reputation · 10 Oct 2024, 01:32 UTC
Buffer objects on a per‑connection basis. The runtime documentation states that a buffer is returned to the pool once the request lifecycle completes, provided the request body has been fully consumed and no external reference remains. If a handler returns a Buffer or stores it in a global structure without draining it, the buffer stays in the pool, leading to a gradual RSS increase.
wrk while watching RSS via top or htop. A steady‑state RSS indicates correct buffer recycling; a linear, non‑plateauing rise signals a leak. For finer granularity, capture heap snapshots with bun --dump-heap before and after the test, or profile with massif.
await request.text() or await request.arrayBuffer()) before responding.Buffer objects; instead, convert to Uint8Array or string if you need to preserve the data.buffer.release() (if exposed) or replace it with a fresh buffer once the request is done.--no-std or other runtime flags to reduce GC pressure if available in future releases.bun serve --port 3000 --watch
// Simple echo handler
Bun.serve({
fetch(req) {
return new Response(req.body);
}
});
wrk -t8 -c200 -d5m http://127.0.0.1:3000/
wrk runs, open another terminal and monitor RSS:
top -p $(pidof bun) -d 1
Observe whether RSS stabilizes or keeps climbing.
bun --dump-heap > before.heap
# Repeat the load test
bun --dump-heap > after.heap
Compare the number of Buffer objects in each file.
massif for native memory profiling:
massif --tool=massif --output=massif.out $(pidof bun)
# After load test, run
massif-analyze massif.out
If your handlers sometimes return raw buffers or store them beyond the request scope, the recommendation above changes. Please confirm whether any part of your code keeps a reference to the request body after the response is sent. This detail determines whether the leak is due to misuse or an internal bug.
bun --dump-heap flag captures JavaScript heap objects but may miss native allocations, so a complete leak picture requires complementary tools like massif.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.