Jarred-Sumner commented Apr 3, 2026 • edited Loading Uh oh!
There was an error while loading.
Please reload this page .
Routes navigator.hardwareConcurrency , os.availableParallelism() , and bun.getThreadCount() through WTF::numberOfProcessorCores() , which is now min(sysconf(_SC_NPROCESSORS_ONLN), sched_getaffinity count, cgroup CPU quota) on Linux.
Under docker run --cpus=2 (or k8s resources.limits.cpu ), the kernel sets a CFS bandwidth quota rather than a cpuset mask.
sysconf and sched_getaffinity both still report the host core count, so on a 96-core host Bun spawns ~96 threads for the thread pool, JSC parallel GC markers, and JIT workers.
Those threads exhaust the 200ms/100ms quota in a few ms of wall time and the entire cgroup is descheduled for the rest of the period — sawtooth latency, nr_throttled climbing, GC stalls mid-collection.
Node returns 2 here (libuv reads cpu.max ); Bun returned 96.
One function now feeds JSC GC/JIT sizing, navigator.hardwareConcurrency , os.availableParallelism() , and Bun's internal thread pool.
robobun commented Apr 3, 2026 • edited Loading Uh oh!
There was an error while loading.
Please reload this page .
❌ @Jarred-Sumner , your commit 1526b00 has 3 failures in Build #43430 ( All Failures ):
That installs a local version of the PR into your bun-28801 executable, so you can run:
github-actions bot commented Apr 3, 2026
Found 1 issues this PR may fix:
If this is helpful, consider adding Fixes #17723 to the PR description to auto-close the issue on merge.
coderabbitai bot commented Apr 3, 2026 • edited Loading Uh oh!
There was an error while loading.
Please reload this page .
Centralized CPU core detection: added Zig/C++ bindings to expose WTF::numberOfProcessorCores(), replaced platform-specific core-count logic with that call, and updated thread and Node OS CPU initialization to use the new APIs.
WebKit prebuilt version hash was updated.
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
Comment @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.
Learn more .
The os.cpus() array mutation bug from my previous comment is already fixed in the current code — lazyCpus correctly uses hostCpuCount (from sysconf, the host CPU count) rather than navigator.hardwareConcurrency, so the array length stays consistent before and after populate().
That said, this PR touches thread pool sizing, JSC GC/JIT worker counts, and has a cross-repo WebKit dependency, so a human should review the architectural decisions.
This PR routes navigator.hardwareConcurrency, os.availableParallelism(), and bun.getThreadCount() through WTF::numberOfProcessorCores(), which on Linux will become min(sysconf, sched_getaffinity, cgroup cpu.max) once the companion WebKit PR lands.
The Bun-side changes are 7 files: new WTF bindings in Zig/C++, updated ZigGlobalObject.cpp, a new bun_sysconf__SC_NPROCESSORS_ONLN() helper, and os.ts/node_os.zig changes.
My prior inline comment flagged that lazyCpus sized the array from navigator.hardwareConcurrency (cgroup-constrained) while the native cpus() binding returns host CPUs, causing silent length mutation on populate().
The current code already addresses this: lazyCpus receives hostCpuCount (from bun_sysconf__SC_NPROCESSORS_ONLN(), the raw sysconf value) and uses it for the array size.
Both sides now agree on the host CPU count.
My previous bug comment was describing a state no longer present in the current code.
No security risks.
This is strictly about CPU count detection and thread pool sizing.
High — this touches getThreadCount() which feeds Bun internal thread pool sizing, and navigator.hardwareConcurrency which feeds JSC GC parallel markers and JIT worker counts.
Getting this wrong (under-counting or over-counting) has direct performance consequences.
The WebKit dependency also means the cgroup behavior only activates once that separate PR lands and the vendored ref is bumped — a non-trivial cross-repo coordination requirement.
The PR description note that os.cpus().length becomes cgroup-constrained appears inconsistent with the actual code, which uses the host CPU count for hostCpuCount.
This discrepancy in documentation vs.
implementation is a minor concern but worth clarifying.
No bugs were found by the automated hunting system.
The change is well-described and solves a real container CPU throttling problem.
Related Stories
Source: This article was originally published by Hacker News
Read Full Original Article →
Comments (0)
No comments yet. Be the first to comment!
Leave a Comment