Prisma: Can't reach database server / too many connections (serverless)
Filed under Supabase & databases
The fix, fast
On serverless hosting, point your app at your database provider’s pooled connection string — for Supabase that is the pooler on port 6543 with ?pgbouncer=true — and add connection_limit=1. Keep a separate direct connection string, on port 5432, only for migrations. Most “Can’t reach database server” and “too many connections” errors come from every short-lived serverless function trying to open its own direct connections.
Why this happens
Prisma is the tool your code uses to talk to the database. A traditional server stays running all day, opens a handful of database connections once, and reuses them. Serverless hosting — Vercel, Netlify, and similar platforms — works the opposite way: every request can spin up a fresh copy of your app, and each copy wants its own connections.
Databases only allow a limited number of connections at once. A few dozen visitors can therefore exhaust them, and Prisma reports a pool timeout or “too many connections.” The related error P1001, “Can’t reach database server,” means Prisma could not even open a connection — the address, port, password, or network path is wrong, or the database is paused or down.
The fix used by Supabase and other hosted Postgres providers is a pooler: a middleman that holds a large pool of real connections and shares them among thousands of short-lived app copies. Your running app should talk to the pooler. Migrations — the commands that change your database’s structure — need a direct connection instead, which is why Prisma supports two URLs.
The fix, step by step
- First, check the database is actually up. Open your provider’s dashboard and confirm the project is not paused (free projects often pause when idle), the project exists in the region you expect, and you can see its connection settings. If the dashboard says paused, resume it and wait a minute before changing any code.
- Get both connection strings from the dashboard. In Supabase, open Connect / Connection string settings. You need the pooled (transaction pooler) string, which uses port 6543, and the direct string, which uses port 5432. Copy them from the dashboard rather than editing an old string by hand, and use the real password — not the placeholder text shown in examples.
- Put the pooled URL in DATABASE_URL and the direct URL in DIRECT_URL. Your environment file — the .env file that holds settings and secrets outside your code — should look like this, with your own host and password:
The# Pooled — used by your running app DATABASE_URL="postgresql://postgres.[project-ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres?pgbouncer=true&connection_limit=1" # Direct — used only for migrations DIRECT_URL="postgresql://postgres:[password]@db.[project-ref].supabase.co:5432/postgres"pgbouncer=truepart tells Prisma the pooler is in charge (PgBouncer is the pooler’s software), andconnection_limit=1stops each serverless copy from grabbing more than one pooled connection. - Tell Prisma to use both URLs in your schema. The schema — the schema.prisma file that describes your database to Prisma — needs a directUrl line, or migrations will try to run through the pooler and fail:
datasource db { provider = "postgresql" url = env("DATABASE_URL") directUrl = env("DIRECT_URL") } - Update the same variables where the app is deployed. Changing your local .env does nothing for the live site. In your hosting dashboard, set DATABASE_URL and DIRECT_URL to the same new values, then redeploy so the new settings take effect. Double-check there are no stray spaces or extra quotes pasted around the values.
- Test locally, then consider a managed pool if it still struggles. Run a page that reads the database and watch for P1001 or timeout errors. If traffic is high and pooling still is not enough, Prisma Accelerate — Prisma’s managed connection pooling and caching service, sometimes still called the Data Proxy in older tutorials — is a supported alternative. Treat it as an upgrade, not the first step; most projects are fixed by steps 2–5 alone.
Give your AI this prompt
I am getting a Prisma database connection error in a serverless deployment. The exact error is:
[paste the full error here, including any code like P1001]
Help me fix the connection setup. Constraints:
- Do not paste, guess, or invent any real password or connection string. Show me placeholders and tell me exactly where to copy the real values from in my provider dashboard.
- Check, in this order: (1) my .env has DATABASE_URL using the pooled connection (Supabase pooler port 6543, with ?pgbouncer=true and connection_limit=1), (2) DIRECT_URL using the direct connection (port 5432), (3) schema.prisma has both url = env("DATABASE_URL") and directUrl = env("DIRECT_URL") in the datasource block.
- Explain in plain English which of those was wrong, if any.
- Make ONE change at a time, tell me how to test it, and wait for my result before suggesting the next change.
- Do not rewrite unrelated files, do not change my models, and do not run migrations without asking me first.