From 180aad15204623dcff16c7fee12d337f69097ae8 Mon Sep 17 00:00:00 2001 From: Chris Parsons <438676+chrisparsons83@users.noreply.github.com> Date: Sat, 21 Mar 2026 09:57:53 -0700 Subject: [PATCH] Fix postgres connection pool leak in development (#195) In dev mode, viteDevServer.ssrLoadModule re-evaluates server/app.ts on every request, creating a new postgres connection pool each time and eventually exhausting Postgres's max_connections limit. Cache the client on globalThis so HMR re-evaluations reuse the same pool. Co-authored-by: Claude Sonnet 4.6 --- server/app.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/server/app.ts b/server/app.ts index 4ba0fd7..c175623 100644 --- a/server/app.ts +++ b/server/app.ts @@ -13,7 +13,14 @@ export const app = express(); if (!process.env.DATABASE_URL) throw new Error("DATABASE_URL is required"); -const client = postgres(process.env.DATABASE_URL); +// In dev, ssrLoadModule re-evaluates this file on every request. Cache the +// client on globalThis so HMR re-loads reuse the same connection pool instead +// of leaking a new one each time. +declare global { + // TypeScript requires `var` in `declare global` blocks — `let`/`const` are not allowed here. + var __pgClient: ReturnType | undefined; // eslint-disable-line no-var +} +const client = (globalThis.__pgClient ??= postgres(process.env.DATABASE_URL)); const db = drizzle(client, { schema }); app.use((_, __, next) => DatabaseContext.run(db, next));