Connection Pooling
beginner*Database connection pooling for serverless and edge environments. Prevents connection exhaustion and handles cold starts gracefully.
$ bunx sinew add database/connection-poolingPrerequisites
- PostgreSQL14+
Or any Prisma-supported database
Tested With
3/3 passing1The Problem
In traditional server environments, you maintain a pool of database connections that get reused across requests. In serverless:
- Each function invocation might create a new connection
- Cold starts create fresh connections
- Connections aren't shared across function instances
- You can easily hit PostgreSQL's default 100 connection limit
2The Solution
Use a connection pooler like PgBouncer or Prisma Accelerate to manage connections externally.
3Files
lib/db.ts
import { PrismaClient } from "@prisma/client";
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
export const prisma =
globalForPrisma.prisma ??
new PrismaClient({
log: process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"],
});
if (process.env.NODE_ENV !== "production") {
globalForPrisma.prisma = prisma;
}lib/db-edge.ts
import { PrismaClient } from "@prisma/client/edge";
import { withAccelerate } from "@prisma/extension-accelerate";
export const prisma = new PrismaClient().$extends(withAccelerate());prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DIRECT_URL")
}
model User {
id String @id @default(cuid())
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}.env.example
# Pooled connection (use for application)
DATABASE_URL="postgresql://user:password@pooler.example.com:6543/mydb?pgbouncer=true"
# Direct connection (use for migrations)
DIRECT_URL="postgresql://user:password@db.example.com:5432/mydb"4Dependencies
$ bun add @prisma/client$ bun add -D prisma5Configuration
Environment Variables
| Variable | Description |
| -------------- | -------------------------------------------------- |
| DATABASE_URL | Pooled connection string for your application |
| DIRECT_URL | Direct connection for migrations and introspection |
Connection String Parameters
Add these to your pooled connection string:
pgbouncer=true- Enables PgBouncer compatibility modeconnection_limit=1- Limits connections per serverless instance
6Usage
// In your API routes or server components
import { prisma } from "@/lib/db";
export async function getUsers() {
return prisma.user.findMany();
}7Troubleshooting
"Too many connections" error
You're hitting your database connection limit. Solutions:
- Use a connection pooler (PgBouncer, Prisma Accelerate, Supavisor)
- Reduce
connection_limitin your connection string - Increase your database's max connections (if self-hosted)
Slow cold starts
The Prisma Client initialization adds ~200-500ms to cold starts. Mitigations:
- Use Prisma Accelerate for edge caching
- Keep functions warm with scheduled pings
- Use smaller Prisma Client bundles with
outputconfiguration
8Edge Runtime
For edge functions (Vercel Edge, Cloudflare Workers), use the edge client with Accelerate:
import { prisma } from "@/lib/db-edge";
export const runtime = "edge";
export async function GET() {
const users = await prisma.user.findMany({
cacheStrategy: { ttl: 60 }, // Cache for 60 seconds
});
return Response.json(users);
}