Scaling Distributed Systems: Vertical Scaling, Horizontal Scaling & Auto Scaling

Dikirimkan pada - Kali Terakhir Diubah Suai pada

Scaling is one of the most important concepts in system design. As traffic increases, applications must handle more requests efficiently without crashing or slowing down.

This article covers vertical scaling, Node.js clustering, autoscaling strategies, capacity estimation, and queue-based architectures for large-scale applications.

Vertical Scaling

What is Vertical Scaling?

Vertical scaling means increasing the resources of a single machine to handle higher traffic.

This includes:- Increasing CPU power- Adding more RAM- Upgrading storage- Better machine configurations

Example:2 CPU + 4GB RAM → 8 CPU + 32GB RAM

Vertical scaling is simple to implement but has hardware limitations.

Limitation in Node.js

Node.js runs on a single-threaded event loop.

This means:- One process typically uses only one CPU core- Multi-core CPUs are not fully utilized automatically

In contrast, languages such as:- Go- Rust- Java

support multithreading and can efficiently utilize multiple CPU cores.

A Naive Approach (Incorrect)

A beginner approach might be manually starting multiple Node.js processes:

node index.jsnode index.jsnode index.jsnode index.jsnode index.jsnode index.jsnode index.jsnode index.js

Problems with This Approach

1. Difficult process management2. Port conflicts between processes3. No built-in load balancing4. No fault tolerance or auto recovery

Solution: Node.js Cluster Module

Node.js provides a built-in cluster module to use multiple CPU cores.

Benefits:- Creates worker processes- Uses multiple CPU cores- Workers share the same port- Requests are distributed automatically

Application Logic (index.js)

import express from 'express'export const app = express()

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

app.get('/', (req, res) => { res.send('Hello World!')})

app.get('/api/:n', (req, res) => { let n = parseInt(req.params.n) let count = 0 if (n > 5000000000) { n = 5000000000 } for (let i = 0; i <= n; i++) { count += i } res.send(`Final count is ${count} (handled by PID ${process.pid})`)})

Cluster Entry (bin.js)

import cluster from 'cluster'import os from 'os'import { app } from './index.js'

const totalCPUs = os.cpus().lengthconst port = 3000

if (cluster.isPrimary) { console.log(`Number of CPUs: ${totalCPUs}`) console.log(`Primary process ${process.pid} is running`)

for (let i = 0; i < totalCPUs; i++) { cluster.fork() }

cluster.on('exit', worker => { console.log(`Worker ${worker.process.pid} died`) console.log('Restarting worker...') cluster.fork() })} else { app.listen(port, () => { console.log(`App listening on port ${port}`) })}

Parallel Computation Using Clusters

Heavy CPU tasks can be divided among workers.

Instead of one process calculating everything sequentially, the workload is split across multiple CPU cores.

Cluster-Based Parallel Computation

import cluster from 'cluster'import os from 'os'

const numCPUs = os.cpus().lengthconst n = 1_000_000_000

if (cluster.isPrimary) { const chunkSize = Math.floor(n / numCPUs) let completed = 0 let totalSum = 0 const startTime = Date.now()

for (let i = 0; i < numCPUs; i++) { const start = i * chunkSize + 1 const end = i === numCPUs - 1 ? n : (i + 1) * chunkSize const worker = cluster.fork()

worker.send({ start, end })

worker.on('message', partialSum => { totalSum += partialSum completed++

if (completed === numCPUs) { const endTime = Date.now() console.log('Total Sum:', totalSum) console.log('Execution Time:', endTime - startTime, 'ms')

for (const id in cluster.workers) { cluster.workers[id]?.kill() } } }) }} else { process.on('message', ({ start, end }) => { let sum = 0 for (let i = start; i <= end; i++) { sum += i } process.send?.(sum) })}

Sequential Computation

const n = 1_000_000_000let sum = 0const start = Date.now()for (let i = 1; i <= n; i++) { sum += i}const end = Date.now()console.log('Sum:', sum)console.log('Time:', end - start, 'ms')

Capacity Estimation

Before scaling, estimate how much traffic your system must handle.

Step 1: Estimate Requests Per Second (RPS)

Example:10,000 users ≈ 100 RPS

Step 2: Measure Server Capacity

Benchmark a single machine.

Example:1 server = 500 RPS

Step 3: Estimate Required Machines

Formula:Total RPS / RPS per machine

Example:1000 RPS / 500 = 2 machines

Autoscaling Groups (ASGs)

Autoscaling automatically adjusts infrastructure based on demand.

Scaling decisions can be based on:- CPU usage- Memory usage- Traffic spikes- Queue length

Benefits:- Saves cost- Handles sudden traffic- Improves availability

Scaling Complex Applications

For high-scale systems, simple server scaling is often not enough.

A queue-based architecture is commonly used.

Architecture Flow

Client → Queue → Workers → Database/Storage → Response

Queue-Based Processing

Typical flow:1. Request arrives2. Request enters a queue3. Workers consume tasks4. Processing happens asynchronously5. Results are stored

Dynamic Worker Scaling

As load increases:More Queue Jobs → More Workers

As load decreases:Fewer Jobs → Fewer Workers

This approach enables efficient horizontal scaling.

Benefits of Queue-Based Systems

- Handles high traffic efficiently- Prevents server overload- Enables horizontal scaling- Improves reliability- Supports asynchronous workloads

Conclusion

Simple applications often scale using better machines and additional servers. However, large-scale systems rely on clustering, autoscaling, queues, and worker architectures to handle millions of requests efficiently.

Understanding when to use vertical scaling, horizontal scaling, or distributed processing is essential for designing reliable systems.

Dipaparkan 1 September, 2026

pankajyadav025

Full Stack Developer | React, Node.js, TypeScript

Need a feature deployed quickly, a clean responsive UI, or an urgent bug fixed? I can help. I am a Full Stack Software Developer with 1.5+ years of professional experience building fast, secure, scalable, and production ready web applications. Whether you need a new web or SaaS application, a Figma to React conversion, a responsive frontend, REST API development, or urgent Node.js backend troubl...

Artikel Seterusnya

Why Good Design Matters More Than Ever for Small Businesses