Skip to content

Forward libpq TCP keepalive / tcp_user_timeout parameters in the PostgreSQL drivers - #7409

Draft
benconda wants to merge 1 commit into
doctrine:4.4.xfrom
benconda:pgsql-tcp-keepalives
Draft

Forward libpq TCP keepalive / tcp_user_timeout parameters in the PostgreSQL drivers#7409
benconda wants to merge 1 commit into
doctrine:4.4.xfrom
benconda:pgsql-tcp-keepalives

Conversation

@benconda

Copy link
Copy Markdown

Fixes #7408.

Summary

The PostgreSQL drivers build their connection string from a fixed whitelist of parameters and silently drop everything else, so libpq's TCP-resilience keywords cannot be configured through DBAL today. This adds support for:

  • keepalives
  • keepalives_idle
  • keepalives_interval
  • keepalives_count
  • tcp_user_timeout
  • connect_timeout

in both PostgreSQL drivers, in the same explicit style already used for the ssl* / gssencmode keywords.

Why

When a TCP connection to PostgreSQL is silently cut mid-query (flaky inter-DC link, stateful firewall dropping an idle entry, LB reset without RST), the PHP process blocks in libpq's recv() until the kernel gives up — with the Linux default net.ipv4.tcp_retries2 = 15 that is ~15 minutes per stuck request, which can exhaust the worker/FPM pool. These libpq keywords bound dead-peer detection to a few seconds, but there was previously no way to set them via DBAL. See #7408 for the full context (real-world incident + measurements).

Changes

  • Driver\PDO\PgSQL\Driver::constructPdoDsn() — append the keywords to the PDO DSN.
  • Driver\PgSQL\Driver::constructConnectionString() — add the keywords to the native pg_connect connection string.
  • Functional connection tests for both drivers (gated on the pgsql/pdo_pgsql phpunit config, like the existing ones).
  • Docs: document the new parameters under pdo_pgsql / pgsql.

Verification

  • phpcs (Doctrine CS) and phpstan pass on the changed files.
  • DSN/conninfo output verified for both drivers, e.g. PDO: pgsql:host=...;...;keepalives=1;keepalives_idle=10;keepalives_interval=5;keepalives_count=3;tcp_user_timeout=15000;connect_timeout=5;

Notes

…drivers

Add support for the libpq connection keywords keepalives, keepalives_idle,
keepalives_interval, keepalives_count, tcp_user_timeout and connect_timeout
in both the pdo_pgsql and pgsql drivers, in the same style as the existing
ssl* keywords.

These bound how long a connection can block when a TCP session is silently
dropped, which otherwise hangs until the kernel exhausts net.ipv4.tcp_retries2
(~15 min by default).

Refs doctrine#7408
@benconda
benconda force-pushed the pgsql-tcp-keepalives branch from f8c1369 to 1a8b607 Compare June 17, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Forward libpq TCP keepalive / tcp_user_timeout parameters in the PostgreSQL drivers

1 participant