DEV Community

KISHAN RAMLAKHAN NISHAD
KISHAN RAMLAKHAN NISHAD

Posted on

Node.js Single-Threading Limits Vertical Scaling Without Extra Modules

Node.js is single-threaded, meaning it runs all tasks in a single CPU core by default. This makes it efficient for handling many requests at once but also creates a limitation:

  • If you upgrade your server to a more powerful one with multiple CPU cores, Node.js won't automatically use them.
  • Instead, it will still run on just one core, leaving the others unused.

To fully use multiple CPU cores, you need extra modules like Cluster or Worker Threads, which help split tasks across multiple cores. Without these, simply adding more CPU power won't improve performance in a Node.js application.

single CPU core ?

Yes, by default, Node.js runs on a single CPU core because it uses a single-threaded event loop to handle requests.

*What does this mean?
*

  • A CPU core is like a worker in a factory. If your computer has 4 cores, it means it can do 4 tasks at the same time.
  • But Node.js, by default, only uses one core to process all tasks, no matter how many cores your machine has.

*Why is this a problem?
*

  • If your server has 8 cores, Node.js will still use just one core, leaving the other 7 cores idle.
  • This means you can’t fully use your CPU power unless you manually enable multi-core processing using modules like Cluster or Worker Threads.

Great! Below is an example of how to use the Cluster module in Node.js to take advantage of multiple CPU cores.

*Step 1: Get the Number of CPU Cores
*

Before running multiple processes, you can check how many CPU cores your machine has using the os module:

const os = require('os');

console.log(`Number of CPU cores: ${os.cpus().length}`);

Enter fullscreen mode Exit fullscreen mode

Step 2: Create a Clustered Node.js Server
The Cluster module allows you to create multiple worker processes, each running on a separate CPU core.

const cluster = require('cluster');
const os = require('os');
const http = require('http');

if (cluster.isMaster) {
    const numCPUs = os.cpus().length; // Get the number of CPU cores

    console.log(`Master process ${process.pid} is running`);
    console.log(`Forking ${numCPUs} worker processes...`);

    // Fork workers (one per CPU core)
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    // Restart worker if it crashes
    cluster.on('exit', (worker, code, signal) => {
        console.log(`Worker ${worker.process.pid} died. Restarting...`);
        cluster.fork();
    });

} else {
    // Worker process - each one runs a separate instance of the HTTP server
    http.createServer((req, res) => {
        res.writeHead(200);
        res.end(`Worker ${process.pid} handled the request`);
    }).listen(3000);

    console.log(`Worker ${process.pid} started`);
}

Enter fullscreen mode Exit fullscreen mode

How It Works:
*The Master Process (cluster.isMaster is true):
*

  • Gets the number of CPU cores.
  • Forks multiple worker processes (one for each core).
  • Monitors worker crashes and restarts them automatically.
    *The Worker Processes (cluster.isMaster is false):
    *

  • Each worker runs an instance of the HTTP server.

  • When a request comes in, one of the workers handles it.

Benefits of Using Clustering:
✅ Uses all available CPU cores for better performance.
✅ If one worker crashes, others keep running, ensuring high availability.
✅ Each worker handles part of the load, reducing response time.

Would you like an example with Worker Threads next? 🚀

Top comments (0)