Scaling Node.js: From Single Thread to High Performance Clusters
Node.js is famous for its non-blocking, event-driven architecture powered by the V8 engine and libuv. However, it suffers from a fundamental limitation: **it runs on a single thread**. This means that by default, a Node.js application, regardless of how powerful the server hardware is, will only utilize **one CPU core**. If you have a 32-core server, 31 cores will sit idle while your application might be struggling under heavy load.
The Solution: Clustering
To solve this, Node.js includes the native **`cluster` module**. This allows you to create child processes (workers) that run simultaneously and share the same server port.
- Master Process: Responsible for spawning workers and restarting them if they crash. It does not handle application logic itself.
- Worker Process: The actual instance of your application. Each worker runs in its own V8 instance with its own memory.
The Challenge of State
Clustering introduces a new complexity: **Shared State**. Since each worker has its own memory, you cannot store user sessions, WebSocket connections, or in-memory caches in a global variable.
❌ In-Memory Session
// Fails in Cluster
global.sessions = {};
// User A connects to Worker 1
// User A next request hits Worker 2
// Worker 2 has no session data!Requests are load-balanced randomly or round-robin.
✔️ Redis Store
// Works in Cluster
const RedisStore = require('connect-redis');
// All workers connect to the
// same Redis database instance.State is externalized, accessible by all workers.
Production Management with PM2
Writing raw cluster code is educational, but in production, we use process managers like **PM2**. PM2 abstracts the clustering logic, offering features like:
- Zero-Downtime Reloads: `pm2 reload all` restarts workers one by one, ensuring the server never drops a connection.
- Log Management: Aggregates logs from all workers into one stream.
- Monitoring: Built-in terminal dashboard to view CPU/RAM usage per worker.
Pro Tip: Always use an odd number of workers or `max - 1` if you are running other databases on the same machine to leave resources for the OS and DB.