Bun: cgroup-aware AvailableParallelism / HardwareConcurrency on Linux

Bun has updated its CPU core detection logic on Linux to respect cgroup quotas, preventing performance issues in containerized environments like Docker and Kubernetes.
Conversation
Routes navigator.hardwareConcurrency (and therefore os.availableParallelism()) through WTF::numberOfProcessorCores() instead of an inline sysconf/sysctl. On Linux this picks up the new sched_getaffinity + cgroup cpu.max capping in WTF, so containers with --cpus=N report N instead of the host core count.
Walkthrough
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.
Why
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.
What
WTF::numberOfProcessorCores() (WebKit side, separate PR): on Linux, also consults sched_getaffinity and a new uv_get_constrained_cpu() that parses /proc/self/cgroup, dispatches v1/v2, and for v2 walks the hierarchy taking the tightest ceil(quota/period). Same file now also walks the v2 hierarchy for memory.max (previously read leaf only). Result is cached after first call.
ZigGlobalObject.cpp:navigator.hardwareConcurrencyusesWTF::numberOfProcessorCores()instead of inlinesysctl/sysconf.wtf-bindings.cpp/WTF.zig: exposeWTF__numberOfProcessorCores()to Zig.bun.zig:getThreadCount()uses it instead ofstd.Thread.getCpuCount().
One function now feeds JSC GC/JIT sizing, navigator.hardwareConcurrency, os.availableParallelism(), and Bun's internal thread pool.
Source: Hacker News












