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 <noreply@anthropic.com>
This commit is contained in:
Chris Parsons 2026-03-21 09:57:53 -07:00 committed by GitHub
parent e2b178221a
commit 180aad1520
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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<typeof postgres> | 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));