iTranslated by AI
How to Resolve Prisma Connection Issues in Next.js and Supabase
Introduction
While developing with Next.js 15 App Router and Supabase, I encountered the following database connection error. I'm documenting it here as a memo for future development.
Conclusion:
Why Session Pooling is essential when using Server Actions
Environment
- Next.js: 15.5.6
- Prisma: 6.18.0
- Supabase (PostgreSQL)
Encountered Error
When trying to save to the database using Server Actions during a form submission, the following error occurred:
// src/app/actions/articles/save-article.ts
"use server";
import prisma from "@/lib/prisma";
export async function saveArticle(articleData: ArticleDataProps, userId: string) {
await prisma.article.create({ // ← Error occurs here
data: {
userId,
...articleData,
},
});
}
Error message:
Can't reach database server at `db.ijbbodiayaqhhhivfntb.supabase.co:5432`
About the Solution
To solve this, it was necessary to change the DATABASE_URL for Session Pooling.
Why is Session Pooling Necessary?
Problems with Connecting via Direct Connection (Port 5432)
┌─────────────────┐
│ Server Action │ ──→ New Connection
├─────────────────┤
│ Server Action │ ──→ New Connection
├─────────────────┤
│ Server Action │ ──→ New Connection ← Connection limit reached!
└─────────────────┘
Next.js 15 Server Actions behave like serverless functions, but problems occurred because their compatibility with Supabase is not ideal due to the following behaviors:
- A new instance starts for each request
- It attempts to establish a new database connection every time
- PostgreSQL has a connection limit (Supabase free plan is 60 connections)
- The connection limit is quickly reached
How Session Pooling (Port 6543) Works
┌─────────────────┐
│ Server Action │ ──┐
├─────────────────┤ │
│ Server Action │ ──┼──→ PgBouncer ──→ Connection Pool ──→ PostgreSQL
├─────────────────┤ │
│ Server Action │ ──┘
└─────────────────┘
Benefits of Session Pooling
- PgBouncer provided by Supabase manages the connections
- Connections are reused, so a new connection is not established every time
- Optimized for serverless environments
- Avoids connection exhaustion issues
Cases Where Direct Connection is Effective vs. Where It Is Not
Cases where Direct Connection can be used
| Environment | Reason |
|---|---|
| Resident servers such as Express/Fastify | Connection pool is maintained |
| Next.js server on VPS/EC2 | The server is resident |
| When running Prisma Migrate | Direct Connection is required for CLI commands |
Cases where Direct Connection is not recommended
| Environment | Reason |
|---|---|
| Next.js App Router + Server Actions | Due to serverless-like behavior |
| Vercel/Netlify deployment | Serverless environment |
| Edge Runtime | Due to lightweight runtime |
Best Practice: Configure Both URLs
In actual development, it is effective to prepare both URLs.
.env file
# Session Pooling (At application runtime)
DATABASE_URL="postgresql://postgres:[PASSWORD]@aws-0-ap-northeast-1.pooler.supabase.com:6543/postgres?pgbouncer=true"
# Direct Connection (When running Prisma Migrate)
DIRECT_URL="postgresql://postgres:[PASSWORD]@db.xxx.supabase.co:5432/postgres"
Prisma Schema
// prisma/schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL") // For application
directUrl = env("DIRECT_URL") // For migration
}
How to obtain the connection string for .env in Supabase
Note: This may change due to UI updates. It was valid as of 2025/10/24 (at the time the screenshot was taken).

Summary
- When using Next.js 15 App Router + Server Actions, switching to Session Pooling (Port 6543) can prevent this error (since Direct Connection (Port 5432) may lead to connection exhaustion in serverless environments).
- Since migrations occur during development, it is a good practice to set both URLs in
.envand use them appropriately inschema.prisma. This saves the trouble of reconfiguration and improves development efficiency.
I ran into a bit of a problem while developing with Supabase, so I think it's a good idea for everyone to set this up in advance!
Discussion