diff --git a/ExpressAPI/src/process/ClusterManager.ts b/ExpressAPI/src/process/ClusterManager.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d49f88429a27268c795ea6b6454ccb62951774d5
--- /dev/null
+++ b/ExpressAPI/src/process/ClusterManager.ts
@@ -0,0 +1,71 @@
+import cluster, { Worker } from 'node:cluster';
+import WorkerRole          from './WorkerRole';
+import os                  from 'os';
+import ClusterStrategy     from './ClusterStrategy';
+import WorkerPool          from './WorkerPool';
+import logger              from '../shared/logging/WinstonLogger';
+
+
+/*
+ This class create a cluster of workers by following the strategy (array of WorkerPool) given in the constructor.
+ */
+class ClusterManager {
+    public static readonly CORES = os.cpus().length;
+
+    private workers: { [pid: number]: WorkerRole; } = [];
+
+    constructor(private strategy: ClusterStrategy) {}
+
+    private getWorkerPool(role: WorkerRole): WorkerPool | undefined {
+        return this.strategy.find(elem => elem.role === role);
+    }
+
+    private runPrimary() {
+        logger.info(`Number of cores: ${ ClusterManager.CORES }`);
+        logger.info(`Primary process is running`);
+
+        this.strategy.forEach(workerPool => {
+            for ( let i = 0 ; i < workerPool.quantity ; i += 1 ) {
+                const worker = cluster.fork({ role: workerPool.role });
+                this.workers[worker.process.pid] = workerPool.role;
+            }
+        });
+
+        // Listen for dying workers and restart them
+        cluster.on('exit', (worker: Worker, code: number) => {
+            logger.info(`Worker ${ worker.process.pid } exited with code ${ code }`);
+
+            const workerRole = this.workers[worker.process.pid];
+
+            const workerPool = this.getWorkerPool(workerRole);
+            if ( workerPool && workerPool.restartOnFail ) {
+                const newWorker = cluster.fork({ role: workerRole });
+                this.workers[newWorker.process.pid] = workerPool.role;
+            }
+
+            delete this.workers[worker.process.pid];
+        });
+    }
+
+    private runWorker() {
+        const workerRole = Number(process.env['role']);
+
+        const workerPool = this.getWorkerPool(workerRole);
+        if ( workerPool ) {
+            workerPool.loadTask().run();
+        } else {
+            logger.warn(`Process task not found for role ${ workerRole }`);
+        }
+    }
+
+    run() {
+        if ( cluster.isPrimary ) {
+            this.runPrimary();
+        } else {
+            this.runWorker();
+        }
+    }
+}
+
+
+export default ClusterManager;
diff --git a/ExpressAPI/src/process/ClusterStrategy.ts b/ExpressAPI/src/process/ClusterStrategy.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4628b6ce90f2b9a8b37d4c1437fdf9bf8a499174
--- /dev/null
+++ b/ExpressAPI/src/process/ClusterStrategy.ts
@@ -0,0 +1,7 @@
+import WorkerPool from './WorkerPool';
+
+
+type ClusterStrategy = Array<WorkerPool>
+
+export default ClusterStrategy;
+ 
\ No newline at end of file
diff --git a/ExpressAPI/src/process/WorkerPool.ts b/ExpressAPI/src/process/WorkerPool.ts
new file mode 100644
index 0000000000000000000000000000000000000000..79c469ee02765ba1b2ee3a59135e16167cc51991
--- /dev/null
+++ b/ExpressAPI/src/process/WorkerPool.ts
@@ -0,0 +1,16 @@
+import WorkerRole from './WorkerRole';
+import WorkerTask from './WorkerTask';
+
+
+/*
+ This interface describe a pool of workers.
+ */
+interface WorkerPool {
+    role: WorkerRole,
+    quantity: number,
+    restartOnFail: boolean,
+    loadTask: () => WorkerTask, //This is a function for lazy load the task (only loaded on function call)
+}
+
+
+export default WorkerPool; 
diff --git a/ExpressAPI/src/process/WorkerRole.ts b/ExpressAPI/src/process/WorkerRole.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ae9ee444ea05f73aef043283ff253c1e155d614f
--- /dev/null
+++ b/ExpressAPI/src/process/WorkerRole.ts
@@ -0,0 +1,7 @@
+enum WorkerRole {
+    None = 0,
+    API  = 1
+}
+
+
+export default WorkerRole;
diff --git a/ExpressAPI/src/process/WorkerTask.ts b/ExpressAPI/src/process/WorkerTask.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d661eb3bff02922ae0e1e79396a2c95e2938b1bc
--- /dev/null
+++ b/ExpressAPI/src/process/WorkerTask.ts
@@ -0,0 +1,6 @@
+interface WorkerTask {
+    run(): void;
+}
+
+
+export default WorkerTask;