Neon error
Prisma P1002 on Neon: Timed out trying to acquire a postgres advisory lock
"Timed out trying to acquire a postgres advisory lock (SELECT pg_advisory_lock(72707369))" is Prisma error P1002. Prisma Migrate waits 10 seconds for that lock, which cannot be changed, and then gives up. On Neon a likely cause is a DATABASE_URL with -pooler in the host: pg_advisory_lock takes a session-level lock, and Neon's docs list session-level advisory locks as not supported on pooled connections. Point migrations at the direct string, the one without -pooler, through directUrl (Prisma 6) or prisma.config.ts (Prisma 7), and keep the pooled string for the app. Another migrate running at the same time gives the same error.
Which Neon connection string does prisma migrate need?
The direct one. Neon's Prisma guide says Prisma CLI commands like prisma migrate and prisma db push need a direct connection for schema operations, and its pooling page lists schema migrations under Direct because tools may not support transaction pooling. The pooled string has -pooler in the host and is for the app's queries. With Neon's Vercel integration, DATABASE_URL is the pooled string and DATABASE_URL_UNPOOLED is the direct one. In Prisma 6 and earlier, directUrl in the datasource block sets the CLI connection; Neon's page says it is available in Prisma 4.10.0 and higher.
// Prisma 6 and earlier: prisma/schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DATABASE_URL_UNPOOLED")
}
// Prisma 7: prisma.config.ts
datasource: {
url: env("DATABASE_URL_UNPOOLED"),
},Why do I also see prepared statement "s0" already exists?
It is the other face of the same mistake. Neon's connection errors page lists "Error undefined: Database error" with the text prepared statement "s0" already exists as Prisma Migrate running over a PgBouncer pooled connection, which it does not support, and tells you to use a direct connection. Prisma's PgBouncer page gives the reason: the Schema Engine is designed to use a single connection to the database. Its workaround is the same, a pooled URL for the app and a direct URL for the CLI.
Error: undefined: Database error
Error querying the database: db error: ERROR: prepared statement "s0" already existsCan I turn the Prisma advisory lock off?
Since Prisma 5.3.0 the PRISMA_SCHEMA_DISABLE_ADVISORY_LOCK environment variable turns it off. Prisma says the lock is there to avoid catastrophic errors, for example when two pull requests merge close together and two migrate commands run at once, and that a command which times out has to be run again. Turning it off hides the pooled-URL problem and removes the guard, so fix the connection string first.
Checklist
How to fix it, then check the fix
- 01Find out which commands touch the schema in your deploy and which URL the datasource uses:
grep -rnE "directUrl|prisma (migrate|db push)" prisma package.json vercel.json .github - 02In Vercel, check the host of the connection string that the build uses. If it contains -pooler, that is the pooled string.
- 03Set the direct string (no -pooler) for the CLI: directUrl in schema.prisma on Prisma 6, or the url in prisma.config.ts on Prisma 7. With the Neon integration it is DATABASE_URL_UNPOOLED.
- 04Keep the pooled string in DATABASE_URL for the running app, then redeploy. A changed variable applies only to new deployments.
- 05Check the fix: the migrate step in the build log finishes without P1002 and the new table shows in the Neon console. If P1002 stays on the direct string, look for a second migrate running at the same time, for example CI and the Vercel build together.
Related
Related guides
Sources
Official docs behind this checklist
- Neon, Connect Prisma to Neon
- Neon, Connection pooling
- Neon, Connection errors
- Neon, Neon-Managed Vercel integration
- Prisma, Configure Prisma Client with PgBouncer
- Prisma, Development and production (v6), Advisory locking
- prisma-engines, postgres.rs (the P1002 message and pg_advisory_lock call)
- PostgreSQL, Advisory lock functions
- Vercel, Environment variables
Browse all launch guides · Read resources · How to make and check your next change
FAQ
FAQ for builders before launch
Can I run prisma migrate through the pooled Neon string?
Neon's docs say no. Its Prisma guide says migrate and db push need a direct connection, and its connection errors page lists Prisma Migrate over a PgBouncer connection as an error with a direct connection as the fix.
Should the app itself use the direct string too?
No. Neon's Prisma page strongly recommends the pooled connection string in DATABASE_URL for the app, and the direct one only for the CLI.
Why did migrations work on my machine?
A local .env often holds a direct string or a local database, while the variable that Vercel gives the build can be the pooled string. Compare the host in each: only the pooled one has -pooler.