.. warning::
- Using external connection poolers, such as PgBouncer, is not compatible
- with prepared statements, because the same client connection may change
- the server session it refers to. If such middleware is used you should
- disable prepared statements, by setting the `Connection.prepare_threshold`
- attribute to `!None`.
+ Unless a connection pooling middleware explicitly declares otherwise, they
+ are not compatible with prepared statements, because the same client
+ connection may change the server session it refers to. If such middleware
+ is used you should disable prepared statements, by setting the
+ `Connection.prepare_threshold` attribute to `!None`.
+
+
+.. _pgbouncer:
+
+Using prepared statements with PgBouncer
+----------------------------------------
+
+Starting from 3.2, Psycopg supports prepared statements when using the
+PgBouncer__ middleware, using the following caveats:
+
+- PgBouncer version must be at least version `1.22`__.
+- The libpq version on the client must be from PostgreSQL 17 or higher.
+
+.. __: https://www.pgbouncer.org/
+.. __: https://www.pgbouncer.org/2024/01/pgbouncer-1-22-0
+
+.. hint::
+
+ If libpq 17 is not available on your client, but PgBouncer is 1.22 or
+ higher, you can still use Psycopg *as long as you disable deallocation*.
+
+ You can do so by setting `Connection.prepared_max` to `!sys.maxsize`.
- Add :ref:`raw-query-cursors` to execute queries using placeholders in
PostgreSQL format (`$1`, `$2`...) (:ticket:`#560`).
- Add `~rows.scalar_row` to return scalar values from a query (:ticket:`#723`).
+- Prepared statements are now :ref:`compatible with PgBouncer <pgbouncer>`.
+ (:ticket:`#589`).
- Add `~Connection.set_autocommit()` on sync connections, and similar
transaction control methods available on the async connections.
- Add support for libpq functions to close prepared statements and portals