Fastify Scaling and Image Processing on Multi-Core VPS
This document outlines strategies for scaling a Fastify application on a multi-core VPS, specifically focusing on handling CPU-intensive tasks like image processing.
1. Core Concepts: Node.js & Multi-core
By default, Node.js (and Fastify) is single-threaded. It runs on one CPU core regardless of how many cores your VPS has. To use all cores, you must run multiple instances or use internal threading.
2. Scaling the Server (The "Horizontal" Approach)
To utilize all 4 cores of your VPS for handling more concurrent requests, you should run multiple processes.
Option A: PM2 Cluster Mode (Easiest)
PM2 is a process manager that handles clustering automatically.
- Command: pm2 start app.js -i max (or -i 4)
- Benefit: If one process crashes, the others keep running. It automatically load-balances incoming traffic.
Option B: Docker & Orchestration
Run the app in containers and scale the replicas.
- Docker Swarm/K8s: Set replicas: 4.
- Reverse Proxy: Use Nginx or HAProxy to distribute traffic between the containers.
3. Handling Image Processing (The "Vertical" Approach)
Image processing is CPU-bound. If done on the main event loop, it will block the API from responding to other users.
Strategy 1: Using 'Sharp' (Internal Threading)
Sharp is the recommended library for image processing in Node.js.
- Why: It uses libvips (C++ library).
- How it handles cores: Sharp maintains its own internal thread pool. Even if your Fastify process is single-threaded, Sharp will offload the work to other threads.
Strategy 2: Worker Threads
If you have custom, heavy CPU logic that isn't handled by a library like Sharp, use the built-in worker_threads module.
- Mechanism: Offloads the calculation to a separate thread so the Fastify event loop stays free to accept new HTTP requests.
Strategy 3: Task Queues (The "Gold Standard")
For very heavy processing (e.g., generating multiple sizes, watermarking, and uploading), use a background job system.
1. API: Receives the image and returns a 202 Accepted immediately.
2. Queue: Use BullMQ or Bee-Queue with Redis.
3. Worker: A separate process (running on its own core) picks up the job and processes the image.
4. Implementation Summary for a 4-Core VPS
| Component | Implementation | Why? |
|---|---|---|
| API Server | Fastify | High performance, low overhead. |
| Process Manager | PM2 (4 instances) | Uses all 4 cores for the event loop. |
| Image Library | Sharp | Fast, C++ based, uses internal threads. |
| Architecture | Nginx -> Fastify (Cluster) | Professional production-grade setup. |
5. Visual Representation
[Image of Node.js cluster architecture with load balancer distributing traffic to multiple worker processes on different CPU cores]