node icon indicating copy to clipboard operation
node copied to clipboard

libuv in node 22.12+ has parallelism bug when running under cgroupsv2

Open ggatus-atlassian opened this issue 7 months ago • 5 comments

Version

22.12

Platform

linux amd64, linux arm64.

Subsystem

libuv

What steps will reproduce the bug?

We identified a recent problem with certain versions of node.js using libuv, where libuv incorrectly reports the number of cpu cores available in certain containerised environments (see https://github.com/libuv/libuv/issues/4740). This bug has been patched, however node.js needs to bump the version of libuv to pull in the fix.

How often does it reproduce? Is there a required condition?

Easy to reproduce via a call to os.availableParallelism() - any logic relying on this function to return the number of available CPU cores is impacted when running inside of a container with cgroups v2.

What is the expected behavior? Why is that the expected behavior?

os.availableParallelism() should return the the correct number of useable CPU cores.

What do you see instead?

When running under cgroupsv2 inside of a machine with 4 cores, we get back a parallelism value of 1. Downgrading either to an earlier node,js version or swapping to cgroupsv1 returns a cpu count of 4.

This manifests to end users as an apparently drop in performance (e.g some test frameworks relying on os.availableParallelism() will spawn less worker threads, slowing down total test execution time. Internally we've seen WebPack performance also degrade due to the same problem.

Additional information

No response

ggatus-atlassian avatar May 23 '25 00:05 ggatus-atlassian

Thanks for opening this issue. I addressed the problem in libuv a few weeks ago and submitted a PR to fix it: https://github.com/libuv/libuv/pull/4746. I also mentioned you in the comments there (https://github.com/libuv/libuv/pull/4746#issuecomment-2764397641) so you could review and test the changes.

I'll look into backporting the latest libuv to the Node.js v22.x line in the next couple of days.

Let me know if the patch fixes your issue. Help me out by testing it :-)

juanarbol avatar May 23 '25 01:05 juanarbol

@juanarbol Ive run the following steps in our CI to build node 22.12 with the latest libuv using ubuntu:latest:

            - >
              apt-get update && apt-get install -y git python3 g++-12 gcc-12 make python3-pip nodejs curl
            - git clone https://github.com/nodejs/node.git
            - cd node
            - git checkout v22.12.0
            - >
              export CXX=g++-12
            - ./configure
            - ./tools/dep_updaters/update-libuv.sh
            - apt remove -y nodejs
            - make -j32
            - make install
            - cd ../
            - node hello.js

hello.js:

const os = require('node:os');
console.log("Available parallelism: " + os.availableParallelism());
console.log("CPUS: " + os.cpus().length);

Output inside of a 32 core pod (running inside of a VM) looks good, it correctly reports the expected parallelism:

Available parallelism: 32
CPUS: 32

Compare this to using the node:latest docker image (which is incorrectly reporting available parallelism):

Available parallelism: 1
CPUS: 32

Looks like the latest libuv successfull reports the number of cores correctly under cgroups v2.

ggatus-atlassian avatar May 23 '25 08:05 ggatus-atlassian

The backport was blocked by Windows 32bits. Not quite sure what's breaking.

Refs: https://github.com/nodejs/node/pull/57316

juanarbol avatar May 23 '25 14:05 juanarbol

Hi @juanarbol, do you know when this fix will be released by any chance? Thanks!

david-ding avatar Jun 05 '25 22:06 david-ding

Hi @juanarbol, do you know when this fix will be released by any chance? Thanks!

I think in the 24th?

https://github.com/nodejs/Release/issues/1001

juanarbol avatar Jun 11 '25 20:06 juanarbol

The fix got released; I'm closing this.

juanarbol avatar Jun 28 '25 15:06 juanarbol