Skip to content

Commit 3512762

Browse files
committed
feat(webapp): per-client database pool and connect timeout overrides
Adds optional per-client env overrides for the Prisma pool_timeout and connect_timeout, one pair each for the writer and read replica of both the primary and run-ops databases, falling back to the shared DATABASE_POOL_TIMEOUT / DATABASE_CONNECTION_TIMEOUT when unset. This lets a fail-fast connect timeout be set for one backend's clients without changing the others. No behavior change until an override is set.
1 parent 3039bc1 commit 3512762

3 files changed

Lines changed: 32 additions & 8 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
area: webapp
3+
type: improvement
4+
---
5+
6+
Allow the database connection pool and connect timeouts to be tuned separately for each writer and read replica, falling back to the shared defaults when unset.

apps/webapp/app/db.server.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,10 @@ export function buildWriterClient({
398398
}): PrismaClient {
399399
const databaseUrl = buildPrismaConnectionUrl(url, {
400400
connectionLimit: env.DATABASE_CONNECTION_LIMIT.toString(),
401-
poolTimeout: env.DATABASE_POOL_TIMEOUT.toString(),
402-
connectTimeout: env.DATABASE_CONNECTION_TIMEOUT.toString(),
401+
poolTimeout: (env.DATABASE_WRITER_POOL_TIMEOUT ?? env.DATABASE_POOL_TIMEOUT).toString(),
402+
connectTimeout: (
403+
env.DATABASE_WRITER_CONNECTION_TIMEOUT ?? env.DATABASE_CONNECTION_TIMEOUT
404+
).toString(),
403405
applicationName: env.SERVICE_NAME,
404406
});
405407

@@ -545,8 +547,10 @@ export function buildReplicaClient({
545547
}): PrismaClient {
546548
const replicaUrl = buildPrismaConnectionUrl(url, {
547549
connectionLimit: env.DATABASE_CONNECTION_LIMIT.toString(),
548-
poolTimeout: env.DATABASE_POOL_TIMEOUT.toString(),
549-
connectTimeout: env.DATABASE_CONNECTION_TIMEOUT.toString(),
550+
poolTimeout: (env.DATABASE_READ_REPLICA_POOL_TIMEOUT ?? env.DATABASE_POOL_TIMEOUT).toString(),
551+
connectTimeout: (
552+
env.DATABASE_READ_REPLICA_CONNECTION_TIMEOUT ?? env.DATABASE_CONNECTION_TIMEOUT
553+
).toString(),
550554
applicationName: env.SERVICE_NAME,
551555
});
552556

@@ -675,8 +679,10 @@ function buildRunOpsWriterClient({
675679
}): RunOpsPrismaClient {
676680
const databaseUrl = buildPrismaConnectionUrl(url, {
677681
connectionLimit: env.DATABASE_CONNECTION_LIMIT.toString(),
678-
poolTimeout: env.DATABASE_POOL_TIMEOUT.toString(),
679-
connectTimeout: env.DATABASE_CONNECTION_TIMEOUT.toString(),
682+
poolTimeout: (env.RUN_OPS_DATABASE_WRITER_POOL_TIMEOUT ?? env.DATABASE_POOL_TIMEOUT).toString(),
683+
connectTimeout: (
684+
env.RUN_OPS_DATABASE_WRITER_CONNECTION_TIMEOUT ?? env.DATABASE_CONNECTION_TIMEOUT
685+
).toString(),
680686
applicationName: env.SERVICE_NAME,
681687
});
682688

@@ -728,8 +734,12 @@ function buildRunOpsReplicaClient({
728734
connectionLimit: (
729735
env.RUN_OPS_DATABASE_READ_REPLICA_CONNECTION_LIMIT ?? env.DATABASE_CONNECTION_LIMIT
730736
).toString(),
731-
poolTimeout: env.DATABASE_POOL_TIMEOUT.toString(),
732-
connectTimeout: env.DATABASE_CONNECTION_TIMEOUT.toString(),
737+
poolTimeout: (
738+
env.RUN_OPS_DATABASE_READ_REPLICA_POOL_TIMEOUT ?? env.DATABASE_POOL_TIMEOUT
739+
).toString(),
740+
connectTimeout: (
741+
env.RUN_OPS_DATABASE_READ_REPLICA_CONNECTION_TIMEOUT ?? env.DATABASE_CONNECTION_TIMEOUT
742+
).toString(),
733743
applicationName: env.SERVICE_NAME,
734744
});
735745

apps/webapp/app/env.server.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ const EnvironmentSchema = z
120120
DATABASE_CONNECTION_LIMIT: z.coerce.number().int().default(10),
121121
DATABASE_POOL_TIMEOUT: z.coerce.number().int().default(60),
122122
DATABASE_CONNECTION_TIMEOUT: z.coerce.number().int().default(20),
123+
DATABASE_WRITER_POOL_TIMEOUT: z.coerce.number().int().optional(),
124+
DATABASE_WRITER_CONNECTION_TIMEOUT: z.coerce.number().int().optional(),
125+
DATABASE_READ_REPLICA_POOL_TIMEOUT: z.coerce.number().int().optional(),
126+
DATABASE_READ_REPLICA_CONNECTION_TIMEOUT: z.coerce.number().int().optional(),
123127
// Dashboard-agent conversation store. Cloud points this at a dedicated
124128
// database; when unset it falls back to DATABASE_URL (OSS), where
125129
// the tables live in the isolated `trigger_dashboard_agent` schema.
@@ -186,6 +190,10 @@ const EnvironmentSchema = z
186190
.optional(),
187191
// Optional cap for the unpooled new run-ops read replica. Unset falls back to DATABASE_CONNECTION_LIMIT.
188192
RUN_OPS_DATABASE_READ_REPLICA_CONNECTION_LIMIT: z.coerce.number().int().optional(),
193+
RUN_OPS_DATABASE_WRITER_POOL_TIMEOUT: z.coerce.number().int().optional(),
194+
RUN_OPS_DATABASE_WRITER_CONNECTION_TIMEOUT: z.coerce.number().int().optional(),
195+
RUN_OPS_DATABASE_READ_REPLICA_POOL_TIMEOUT: z.coerce.number().int().optional(),
196+
RUN_OPS_DATABASE_READ_REPLICA_CONNECTION_TIMEOUT: z.coerce.number().int().optional(),
189197
// Direct DSN for applying the full @trigger.dev/database migrations to the LEGACY run-ops DB, keeping
190198
// its schema current after the control plane moves off it. Direct, not pooled — migrations never run
191199
// over a pooler. Optional; unset -> the entrypoint's legacy migrate step is skipped.

0 commit comments

Comments
 (0)