Careeroza
Connection Reuse in Development
The Hot Reload Problem
In next dev, files are re-evaluated on every change. If lib/prisma.ts does new PrismaClient() at the top level, each reload opens a new connection pool, and soon PostgreSQL says "too many clients already". The fix: store the client on globalThis, which survives reloads.
lib/prisma.ts
import { PrismaClient } from '@prisma/client';
const globalForPrisma = globalThis as unknown as { prisma?: PrismaClient };
export const prisma =
globalForPrisma.prisma ??
new PrismaClient({ log: process.env.NODE_ENV === 'development' ? ['query', 'warn', 'error'] : ['error'] });
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;Why It Works
Example
Simulate three hot reloads of the module. Without the global, each reload creates a new pool:
class Pool {
static created = 0;
readonly id = ++Pool.created;
}
const g = globalThis as unknown as { pool?: Pool };
function loadModuleNaive(): Pool {
return new Pool();
}
function loadModuleWithGlobal(): Pool {
const pool = g.pool ?? new Pool();
g.pool = pool;
return pool;
}
for (let i = 1; i <= 3; i++) loadModuleNaive();
console.log('naive: pools created =', Pool.created);
Pool.created = 0;
const ids = [1, 2, 3].map(() => loadModuleWithGlobal().id);
console.log('global: pool ids =', ids.join(', '), '| pools created =', Pool.created);Output
naive: pools created = 3 global: pool ids = 1, 1, 1 | pools created = 1
Serverless and Edge
- On serverless platforms each function instance has its own pool. Use a pooler (PgBouncer, Prisma Accelerate, Neon/Supabase pooled URL) so hundreds of instances do not exhaust the database.
- Prisma needs the Node.js runtime unless you use a driver adapter. Keep database pages on
runtime = 'nodejs'(the default).