Disabling Prepared statements
Direct connections and the shared pooler (Supavisor) in session mode support prepared statements. The dedicated pooler supports them on PgBouncer 1.21 and later. The shared pooler in transaction mode doesn’t support them.
How to disable prepared statements for the shared pooler in transaction mode
Each ORM or library configures prepared statements differently. Here are settings for some common ones. If you don’t see yours, make a comment
Prisma:
add ?pgbouncer=true to end of connection string:
postgres://[db-user].[project-ref]:[db-password]@aws-0-[aws-region].pooler.supabase.com:6543/[db-name]?pgbouncer=trueDrizzle:
Add a prepared false flag to the client:
export const client = postgres(connectionString, { prepare: false })Node Postgres
Omit the “name” value in a query definition:
const query = { name: 'fetch-user', // <--------- DO NOT INCLUDE text: 'SELECT * FROM user WHERE id = $1', values: [1],}Psycopg
set the prepare_threshold to None.
asyncpg
Follow the recommendation in the asyncpg docs
disable automatic use of prepared statements by passing
statement_cache_size=0to asyncpg.connect() and asyncpg.create_pool() (and, obviously, avoid the use of Connection.prepare());
JDBC
Set prepareThreshold to 0:
jdbc:postgresql://[POOLER-HOST]:6543/postgres?prepareThreshold=0Rust’s Deadpool or tokio-postgres:
- Check GitHub Discussion
Related topics
- Connection pooling and limits
- Error: prepared statement already exists
- Supavisor FAQ
- Prisma error management