Course contentsShow
← Node.js
Lesson 69 of 1,9801. Node.js Foundations and Runtime InternalsFree lesson

Load Balancing and Process Affinity

Configure process affinity to improve cache locality in multi-core deployments.

In this lesson, you will learn how to bind your Node.js processes to specific CPU cores to maximize cache efficiency and improve application performance.

Understanding Process Affinity

When you use clustering to scale your application across multiple cores, the operating system's scheduler decides which core runs your process at any given moment. By default, the OS might move your process from Core 0 to Core 2 to balance overall system load. While this keeps the system fair, it is bad for your application's speed.

Modern CPUs rely heavily on L1, L2, and L3 caches. These caches store the data and instructions your code uses most frequently. If your process is constantly "jumping" between cores, it loses access to the data stored in the local cache of the previous core. It then has to reload that data from the slower main memory (RAM).

Process Affinity (also called CPU pinning) is the practice of "locking" a specific Node.js worker process to a specific physical CPU core. This ensures that the data your process needs stays "warm" in that core’s local cache, significantly reducing latency.

Implementing Affinity

In Node.js, we often use the os module to detect how many cores are available, but to actually enforce affinity, we use OS-level tools or libraries like taskset on Linux.

Imagine you are spinning up workers in your cluster. If you have 4 cores, you want Worker 0 to stay on Core 0, Worker 1 on Core 1, and so on:

const { spawn } = require('child_process');

// Pinning a worker to CPU Core 0 using the Linux 'taskset' command
const worker = spawn('taskset', ['-c', '0', 'node', 'worker.js']);

By keeping the process on the same core, your V8 engine’s "hot" functions and objects remain in the CPU cache. This minimizes the "cache miss" penalties that would otherwise occur if the process were migrated, leading to smoother execution and more consistent latency percentiles.

Key Takeaway: By pinning Node.js processes to specific CPU cores, you prevent context switching and cache invalidation, ensuring your application’s working data remains readily available in the local CPU cache for faster execution.