Demo, all content is generated
Question

Prisma on Vercel: 'prepared statement "s0" already exists' with Supabase

Solved · 2806 views · asked by nightshiftbuilder · edited

Deployed my Next.js app to Vercel. Pages that query through Prisma randomly 500:

PrismaClientUnknownRequestError: Error occurred during query execution:
ConnectorError(ConnectorError { user_facing_error: None, kind: QueryError(PostgresError { code: "42P05", message: "prepared statement \"s0\" already exists" ... 

Locally never. DATABASE_URL uses port 6543 because a guide said serverless should use that.

What I’ve tried

Redeployed, cleared the Vercel cache, regenerated the Prisma client.

Comment
Is there ?pgbouncer=true at the end of your DATABASE_URL? rafa_dev · edited

3 answers

Marked as helpful by the asker
rafa_dev · edited

The guide was right about 6543 (transaction pooler), but Prisma needs to know it's behind a pooler so it stops using prepared statements:

DATABASE_URL="postgresql://postgres.<ref>:<pw>@aws-0-<region>.pooler.supabase.com:6543/postgres?pgbouncer=true&connection_limit=1"
DIRECT_URL="postgresql://postgres.<ref>:<pw>@aws-0-<region>.pooler.supabase.com:5432/postgres"
datasource db {
  provider  = "postgresql"
  url       = env("DATABASE_URL")
  directUrl = env("DIRECT_URL")
}

pgbouncer=true turns off prepared statements. connection_limit=1 keeps each serverless instance to one connection. directUrl is used by prisma migrate, which needs a session connection.

Comment
Fixed, 2 days of errors gone. Thanks nightshiftbuilder · edited
Remember to set both env vars for Preview too, not only Production. That's the next ticket people open. jonas_k · edited
wes_codes · edited

Confirming this. Also works the same with any PgBouncer, not just Supabase.

Comment
kofi_mensah · edited

Not Prisma-specific by the way: any client that prepares statements behaves like this behind the transaction pooler. psycopg 3 needs prepare_threshold=None, postgres-js needs prepare: false.

Comment