iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🎃

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
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 .env and use them appropriately in schema.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!

References

Discussion