The first time I set up Prisma in a Next.js app, everything worked perfectly. Local dev, queries flying, no complaints.
Then I deployed to Vercel.
Within 10 minutes I had 500 errors. The logs were full of PrismaClientInitializationError and something about "too many connections." I'd hit the database connection limit. On a side project with zero real users.
Here's what happened: Next.js in development mode does hot reloading. Every time you save a file, modules re-evaluate. If you just do export const prisma = new PrismaClient() at the top of some lib/prisma.ts file without any protection, you'll create a brand new PrismaClient on every hot reload. Each client opens its own connection pool. Twenty saves later, you've got twenty pools open against your database.
The fix is embarrassingly simple once you know it:
ts
const globalForPrisma = global as unknown as { prisma: PrismaClient }
export const prisma =
globalForPrisma.prisma ?? new PrismaClient()
if (process.env.NODE_ENV !== 'production')
globalForPrisma.prisma = prismaYou stick the client on the global object. Node's global persists across hot reloads. So the second time the module evaluates, it finds the existing client instead of making a new one. In production you skip this entirely because there's no hot reloading — each serverless function gets one client, does its work, and exits.
The thing is, this pattern is buried in Prisma's docs under "best practices." It's not in the quickstart. It's not what you find when you Google "prisma nextjs setup." You find the simple version, deploy it, break something in production, and then find the real answer at 11pm.
If you're using the App Router, there's an extra wrinkle. Server Components run in a weird in-between world — not quite serverless, not quite persistent. The singleton pattern still applies, but you also have to be careful about where you're importing prisma. Importing it inside a Client Component file will break everything because Prisma is Node-only. Keep your database calls inside Server Components, Route Handlers, or Server Actions. Draw that line clearly and don't let it blur.
One more thing: if you're on a connection-limited database like Neon or PlanetScale's free tier, add log: ['warn', 'error'] to your PrismaClient options so you can actually see what's happening. Silent connection exhaustion is the worst kind.


Comments (0)
Sign in to join the conversation.
No comments yet. Be the first to share your thoughts.