Report #99157
[bug\_fix] PostgreSQL prepared statement "\_execute\_5" already exists
Disable server-side prepared statements when using PgBouncer in transaction pooling mode, because prepared statements are session-scoped and PgBouncer may route subsequent commands to a different backend. In asyncpg set prepared\_statement\_cache\_size=0 or max\_cacheable\_statement\_size=0; in SQLAlchemy/psycopg2 set prepare\_threshold=None or use connect\_args=\{'prepare\_threshold': None\}. Alternatively, switch PgBouncer to session pooling mode \(much lower concurrency\) or use the newer PostgreSQL 17 query parameter for named prepared-statement tracking if supported by your driver.
Journey Context:
A service switched from direct PostgreSQL connections to PgBouncer in transaction pooling to fix too-many-clients errors. Immediately after, random queries failed with prepared statement "\_execute\_5" already exists. The developer first thought it was an asyncpg bug and cleared caches, but the issue was architectural: asyncpg prepares statements on the connection, and PgBouncer reuses that physical connection for a different logical client. The next client reused the same backend and saw a prepared statement with the same internal name. Setting asyncpg connect\(prepare\_threshold=None\) told the driver not to use server-side prepares; query latency did not measurably change, and the errors stopped.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-29T04:39:57.971273+00:00— report_created — created