Skip to content

docs: say what PgBouncer compatibility depends on, and what pre-ping costs behind it - #67

Merged
AlexeyShalaev merged 1 commit into
masterfrom
docs/58-60-pgbouncer
Oct 16, 2026
Merged

AlexeyShalaev merged 1 commit into
masterfrom
docs/58-60-pgbouncer

Conversation

@AlexeyShalaev

Copy link
Copy Markdown
Member

Closes #58.
Closes #60.

One PR for both: they rewrite the same PgBouncer section of the configuration guide, the same paragraph of the advanced guide, and rule 16 on the agents page. Docs and docstrings only, no behaviour change.

#60: what makes the library safe behind PgBouncer

The docs credited AsyncCConnection (uuid statement names) and the "1.22" version boundary. Both were wrong:

  • With statement_cache_size=0 (the default) asyncpg sends unnamed statements and never asks the connection class for a name. That is what makes any PgBouncer work. With statement_cache_size > 0, PgBouncer has to track prepared statements itself, and AsyncCConnection and a plain asyncpg.Connection passed and failed in exactly the same runs (the issue's table, reproduced on 1.25.2).

  • Version defaults, measured on stock images with nothing set:

    PgBouncer 1.21.0     max_prepared_statements=0
    PgBouncer 1.22.1     max_prepared_statements=0
    PgBouncer 1.23.1     max_prepared_statements=0
    PgBouncer 1.24.1     max_prepared_statements=200
    PgBouncer 1.25.2     max_prepared_statements=200
    

    This matches the PgBouncer changelog: the feature arrived in 1.21.0 behind the setting, and the default became 200 in 1.24.0.

Changed: the PgBouncer section, the advanced guide's compatibility paragraph, rule 16, and the create_async_session_manager intro on the agents page. The table row "(the default before 1.22)" now says 1.24. The AsyncCConnection docstring and the connection_class argument doc describe what the class does and no longer claim PgBouncer compatibility. connection_class keeps defaulting to AsyncCConnection: it's harmless, and swapping a default that does nothing is churn.

#58: what pre-ping costs behind a transaction-mode PgBouncer

Reproduced on PgBouncer 1.25.2 with the issue's script: 20 PgBouncer transactions for 10 requests with pre_ping=True versus 10 without, and with pre_ping=True a 1.0 s checkout wait on a pool with timeout=0.2 and no timeout counted.

The docs now say so: in the PgBouncer section, rule 16, and the advanced guide. The PgBouncer examples show PoolSettings(pre_ping=False, recycle=300). The pool settings table points pre_ping at the PgBouncer section, and the "turns into connection_timeouts_total at pool_timeout" sentences (configuration guide, advanced guide, rule 17) are qualified: that holds for the pool's own queue only. The default stays True, which is right for direct connections.

The recycle advice was measured too, with PgBouncer client_idle_timeout=2, one request, 3 s idle, one request:

pre_ping=True,  recycle=3600: first ok; after idle ok
pre_ping=False, recycle=3600: first ok; after idle InterfaceError: connection is closed
pre_ping=False, recycle=1   : first ok; after idle ok

Gate

make check clean; make test 626 passed. The docs build's only warning is the pre-existing changelog.md link, which the Makefile target copies in before building.

Lab scripts: the two issue scripts as posted, plus the version/idle-timeout lab above (testcontainers, edoburu/pgbouncer images 1.21.0-p2 through v1.25.2-p0).

Overlaps with #63 (the connection_timeouts_total wording) in docs/agents.md and the advanced guide. I'll rebase whichever lands second.

@codecov

codecov Bot commented Oct 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@AlexeyShalaev
AlexeyShalaev merged commit 06d9ffa into master Oct 16, 2026
8 checks passed
@AlexeyShalaev
AlexeyShalaev deleted the docs/58-60-pgbouncer branch October 16, 2026 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant