Report #98710
[bug\_fix] PostgreSQL through PgBouncer: ERROR: prepared statement "..." does not exist
PgBouncer in transaction pool mode assigns a different Postgres backend for every transaction, so server-side prepared statements created on one backend are not present on the next. Disable named/extended prepared statements in the client: in psycopg3 set prepare\_threshold=None; in Prisma add ?pgbouncer=true; in SQLAlchemy with psycopg2 use prepared\_statement\_cache\_queries=0; in pgx use default\_query\_exec\_mode=exec or PreferSimpleProtocol. Alternatively, switch PgBouncer to session mode, which keeps one backend per client but reduces connection reuse.
Journey Context:
Your Node.js/Python app works fine against Postgres directly, but after pointing it at PgBouncer in transaction mode you see ERROR: prepared statement "S\_243" does not exist or unnamed prepared statement does not exist. The PARSE step ran on backend X, then the transaction ended and PgBouncer returned backend X to the pool; the next EXECUTE landed on backend Y, which has never heard of that statement. PgBouncer is behaving correctly: it multiplexes connections, it does not replicate session state. The fix is to tell the driver not to use server-side prepared statements. With psycopg3 this is prepare\_threshold=None; with JDBC it is prepareThreshold=0&preparedStatementCacheQueries=0. After that, every query is sent as a simple/unnamed protocol message and the backend reassignment no longer matters.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-28T04:38:59.922576+00:00— report_created — created