From 45605f56c0fdfea1f086e3e7ef0c97ead5c0fe58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=E1=BA=A7n=20B=C3=A1ch?= <45133811+barttran2k@users.noreply.github.com> Date: Tue, 7 Apr 2026 00:17:38 +0700 Subject: [PATCH 1/2] perf: ajv schema compiled on every validation call (api. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In `backend/lib/validator/api.js`, `ajv.compile(schema)` is called inside `apiValidator` on every single request. AJV schema compilation is computationally expensive and should be done once per schema, then the compiled validate function should be reused. Under load, this causes significant CPU overhead on every API request that involves validation. Affected files: api.js, index.js Signed-off-by: Trần Bách <45133811+barttran2k@users.noreply.github.com> --- backend/lib/validator/api.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/lib/validator/api.js b/backend/lib/validator/api.js index 6c738d5097..9dfa0e62d6 100644 --- a/backend/lib/validator/api.js +++ b/backend/lib/validator/api.js @@ -9,6 +9,8 @@ const ajv = new Ajv({ coerceTypes: true, }); +const compiledSchemas = new WeakMap(); + /** * @param {Object} schema * @param {Object} payload @@ -25,7 +27,11 @@ const apiValidator = async (schema, payload /*, description*/) => { } - const validate = ajv.compile(schema); + let validate = compiledSchemas.get(schema); + if (!validate) { + validate = ajv.compile(schema); + compiledSchemas.set(schema, validate); + } const valid = validate(payload); From 897762c32c72d566edcfab18aa47f2afe750f3ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=E1=BA=A7n=20B=C3=A1ch?= <45133811+barttran2k@users.noreply.github.com> Date: Tue, 7 Apr 2026 00:17:39 +0700 Subject: [PATCH 2/2] perf: ajv schema compiled on every validation call (api. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In `backend/lib/validator/api.js`, `ajv.compile(schema)` is called inside `apiValidator` on every single request. AJV schema compilation is computationally expensive and should be done once per schema, then the compiled validate function should be reused. Under load, this causes significant CPU overhead on every API request that involves validation. Affected files: api.js, index.js Signed-off-by: Trần Bách <45133811+barttran2k@users.noreply.github.com> --- backend/lib/validator/index.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/lib/validator/index.js b/backend/lib/validator/index.js index 5f2586fd67..19eb9a3c80 100644 --- a/backend/lib/validator/index.js +++ b/backend/lib/validator/index.js @@ -14,6 +14,8 @@ const ajv = new Ajv({ schemas: [commonDefinitions], }); +const compiledSchemas = new WeakMap(); + /** * * @param {Object} schema @@ -26,7 +28,11 @@ const validator = (schema, payload) => { reject(new errs.InternalValidationError("Payload is falsy")); } else { try { - const validate = ajv.compile(schema); + let validate = compiledSchemas.get(schema); + if (!validate) { + validate = ajv.compile(schema); + compiledSchemas.set(schema, validate); + } const valid = validate(payload); if (valid && !validate.errors) {