From 9b62957052518944bec21f0dd610845c5e90c6c8 Mon Sep 17 00:00:00 2001 From: null Date: Wed, 8 Jul 2026 02:44:06 -0500 Subject: [PATCH] =?UTF-8?q?fix(functions):=20lower=20global=20maxInstances?= =?UTF-8?q?=2020=E2=86=925=20to=20fit=20the=20Cloud=20Run=20CPU=20quota?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2nd-gen deploy failed with "Quota exceeded for total allowable CPU per project per region": each function is a Cloud Run service and the regional CPU-allocation quota is charged as the sum of (maxInstances × vCPU) across all functions. At maxInstances 20 × ~34 v2 functions = ~680 vCPU, over this new project's default (~560). Dropping to 5 → 170 vCPU, well under. 5 instances × ~80 concurrent requests still serves ~400 in flight — fine pre-launch. For production, request a Cloud Run CPU quota increase and raise this back up. Co-Authored-By: Claude Opus 4.8 --- functions/dist/options.js | 11 ++++++++--- functions/dist/options.js.map | 2 +- functions/src/options.ts | 11 ++++++++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/functions/dist/options.js b/functions/dist/options.js index 7e3c4cd1..7d989c3d 100644 --- a/functions/dist/options.js +++ b/functions/dist/options.js @@ -9,13 +9,18 @@ const v2_1 = require("firebase-functions/v2"); * no region override (di/SecurityModule.kt, data/remote/FirestoreAnswerDataSource.kt), so the * callables MUST live in us-central1 or every install breaks. Do not change without also * pinning the client. - * maxInstances: a runaway-bill guardrail, not a throughput target (v2 serves ~80 concurrent - * requests per instance, so 20 instances is ample at current scale). Revisit at launch. + * maxInstances: a runaway-bill guardrail AND a Cloud Run quota constraint. Each 2nd-gen function + * is a Cloud Run service, and the project's regional "total CPU allocation" quota is charged as + * the SUM of (maxInstances x vCPU) across every function. With ~34 v2 functions and a new + * project's default quota (~560 vCPU in us-central1), this must stay low or deploys fail with + * "Quota exceeded for total allowable CPU per project per region". 5 x 34 = 170, well under. + * For production: request a Cloud Run CPU quota increase (console → IAM & Admin → Quotas) and + * raise this. ~80 concurrent requests per instance means 5 instances still serves ~400 in flight. * * This module is imported FIRST in index.ts so these options are set before any v2 function is * defined. It has no effect on the one v1 holdout (onUserDelete), which keeps its own defaults. */ -(0, v2_1.setGlobalOptions)({ region: 'us-central1', maxInstances: 20 }); +(0, v2_1.setGlobalOptions)({ region: 'us-central1', maxInstances: 5 }); /** Region constant for any per-function override that ever needs to pin it explicitly. */ exports.REGION = 'us-central1'; //# sourceMappingURL=options.js.map \ No newline at end of file diff --git a/functions/dist/options.js.map b/functions/dist/options.js.map index 67557bdb..c235291f 100644 --- a/functions/dist/options.js.map +++ b/functions/dist/options.js.map @@ -1 +1 @@ -{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":";;;AAAA,8CAAwD;AAExD;;;;;;;;;;;;GAYG;AACH,IAAA,qBAAgB,EAAC,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAA;AAE7D,0FAA0F;AAC7E,QAAA,MAAM,GAAG,aAAa,CAAA"} \ No newline at end of file +{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":";;;AAAA,8CAAwD;AAExD;;;;;;;;;;;;;;;;;GAiBG;AACH,IAAA,qBAAgB,EAAC,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,CAAA;AAE5D,0FAA0F;AAC7E,QAAA,MAAM,GAAG,aAAa,CAAA"} \ No newline at end of file diff --git a/functions/src/options.ts b/functions/src/options.ts index 6a45999f..21ed7053 100644 --- a/functions/src/options.ts +++ b/functions/src/options.ts @@ -7,13 +7,18 @@ import { setGlobalOptions } from 'firebase-functions/v2' * no region override (di/SecurityModule.kt, data/remote/FirestoreAnswerDataSource.kt), so the * callables MUST live in us-central1 or every install breaks. Do not change without also * pinning the client. - * maxInstances: a runaway-bill guardrail, not a throughput target (v2 serves ~80 concurrent - * requests per instance, so 20 instances is ample at current scale). Revisit at launch. + * maxInstances: a runaway-bill guardrail AND a Cloud Run quota constraint. Each 2nd-gen function + * is a Cloud Run service, and the project's regional "total CPU allocation" quota is charged as + * the SUM of (maxInstances x vCPU) across every function. With ~34 v2 functions and a new + * project's default quota (~560 vCPU in us-central1), this must stay low or deploys fail with + * "Quota exceeded for total allowable CPU per project per region". 5 x 34 = 170, well under. + * For production: request a Cloud Run CPU quota increase (console → IAM & Admin → Quotas) and + * raise this. ~80 concurrent requests per instance means 5 instances still serves ~400 in flight. * * This module is imported FIRST in index.ts so these options are set before any v2 function is * defined. It has no effect on the one v1 holdout (onUserDelete), which keeps its own defaults. */ -setGlobalOptions({ region: 'us-central1', maxInstances: 20 }) +setGlobalOptions({ region: 'us-central1', maxInstances: 5 }) /** Region constant for any per-function override that ever needs to pin it explicitly. */ export const REGION = 'us-central1'