From b189c308e5e78a34828dd2fc18f8d2597047f5b0 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sat, 30 May 2026 16:48:31 -0400 Subject: [PATCH] perf: Avoid loading unused services (#12537) * fix: Run single process when only the worker service is enabled Co-Authored-By: Claude Opus 4.8 * perf: Improve memory consumption through lazy service loading --------- Co-authored-by: Claude Opus 4.8 --- server/index.ts | 9 ++++++--- server/services/index.ts | 29 +++++++++++++++-------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/server/index.ts b/server/index.ts index 98132d0a28..549244b1a5 100644 --- a/server/index.ts +++ b/server/index.ts @@ -184,8 +184,8 @@ async function start(_id: number, disconnect: () => void) { } Logger.info("lifecycle", `Starting ${name} service`); - const init = services[name as keyof typeof services]; - await init(app, server as https.Server, env.SERVICES); + const { default: init } = await services[name as keyof typeof services](); + await Promise.resolve(init(app, server as https.Server, env.SERVICES)); } server.on("error", (err) => { @@ -258,8 +258,11 @@ const isWebProcess = env.SERVICES.includes("api") || env.SERVICES.includes("collaboration"); +const isWorkerProcess = + env.SERVICES.length === 1 && env.SERVICES.includes("worker"); + void throng({ master, worker: start, - count: isWebProcess ? webProcessCount : undefined, + count: isWorkerProcess ? 1 : isWebProcess ? webProcessCount : undefined, }); diff --git a/server/services/index.ts b/server/services/index.ts index 990e944ac4..62fccc88f3 100644 --- a/server/services/index.ts +++ b/server/services/index.ts @@ -1,15 +1,16 @@ -import admin from "./admin"; -import collaboration from "./collaboration"; -import cron from "./cron"; -import web from "./web"; -import websockets from "./websockets"; -import worker from "./worker"; - -export default { - websockets, - collaboration, - admin, - web, - worker, - cron, +/** + * Services are lazily imported so that only the modules for the services + * actually being run are loaded into memory. For example, a worker-only + * process does not need to import the web or collaboration services and their + * (often heavy) dependency trees. + */ +const services = { + websockets: () => import("./websockets"), + collaboration: () => import("./collaboration"), + admin: () => import("./admin"), + web: () => import("./web"), + worker: () => import("./worker"), + cron: () => import("./cron"), } as const; + +export default services;