How to Harness Node.js Worker Threads with Shared Memory and CGroup Limits

This article demonstrates creating Node.js Worker Threads to compute Fibonacci numbers, explains message passing via workerData and parentPort, explores shared memory with SharedArrayBuffer, and shows how to isolate and limit thread CPU usage using Linux CGroup controls, including retrieving thread IDs via a custom native addon.

Node Underground
Node Underground
Node Underground
How to Harness Node.js Worker Threads with Shared Memory and CGroup Limits

Creating a Worker Thread

Node.js uses an event‑loop model; long‑running calculations block the loop and reduce throughput. Worker Threads can offload occasional CPU‑intensive work such as computing a Fibonacci sequence.

const { Worker } = require('worker_threads');
const worker = new Worker('./thread.js', {
  workerData: { number: 10 }
});
worker.on('message', result => {
  console.log(result);
});

In thread.js the worker receives workerData, computes the Fibonacci number and sends the result back via parentPort.

const { workerData, parentPort } = require('worker_threads');
const { number } = workerData;
parentPort.postMessage(fib(number));
function fib(n) {
  return n < 1 ? 0 :
         n <= 2 ? 1 :
         fib(n-1) + fib(n-2);
}

Key points

Initial data can be passed to a worker through workerData. parentPort provides a MessageChannel for communication between parent and worker.

MessageChannel details

The messages are transferred using the HTML structured clone algorithm, which unlike JSON can handle circular references, built‑in types such as RegExp, BigInt, Map, Set, and binary buffers like ArrayBuffer or SharedArrayBuffer.

Shared memory

Primitive values are copied, but a SharedArrayBuffer allows true shared memory between threads.

const { Worker } = require('worker_threads');
const worker = new Worker('./thread.js', {
  workerData: { number: 10 }
});
const sharedUint8Array = new Uint8Array(new SharedArrayBuffer(4));
const msg = { buffer: sharedUint8Array };
worker.postMessage(msg);
worker.on('message', result => {
  console.log('at main', result, msg);
});

In the worker the buffer is filled with a value and the result is posted back.

const { workerData, parentPort } = require('worker_threads');
const { buffer } = workerData;
buffer.fill(5, 0, 4);
console.log('at worker', { buffer });
parentPort.postMessage('ok');

Running the program shows both the main thread and the worker see the same filled buffer.

Isolation and CPU limitation

When deploying on serverless/FaaS platforms, limiting a worker’s CPU can be useful. The example shows how to obtain the Linux thread ID (TID) via a custom native addon that calls syscall(SYS_gettid), then place that TID into a CGroup.

#include <node.h>
#include <v8.h>
#include <unistd.h>
#include <sys/syscall.h>
pid_t gettid(void) { return syscall(SYS_gettid); }
// ...export gettid as a Node.js function...

After building the addon, the worker prints its PID, TID and WorkerThreadId.

PID: 9041, TID: 9048, WorkerThreadId: 1
PID: 9041, TID: 9049, WorkerThreadId: 2

Using cgcreate and cgset a CGroup named wt is created with a 25 % CPU quota, and the TIDs are added to the group via echo TID > /sys/fs/cgroup/cpu/wt/tasks. The top -H output confirms the CPU usage drops to the configured limits.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Node.jscgroupSharedArrayBufferWorker Threads
Node Underground
Written by

Node Underground

No language is immortal—Node.js isn’t either—but thoughtful reflection is priceless. This underground community for Node.js enthusiasts was started by Taobao’s Front‑End Team (FED) to share our original insights and viewpoints from working with Node.js. Follow us. BTW, we’re hiring.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.