Skip to content

pg-pool: enable TCP keepalive and retry once on connection-drop errors - #532

Open
16francej wants to merge 1 commit into
mainfrom
fix/pg-pool-connection-resilience
Open

pg-pool: enable TCP keepalive and retry once on connection-drop errors#532
16francej wants to merge 1 commit into
mainfrom
fix/pg-pool-connection-resilience

Conversation

@16francej

@16francej 16francej commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Problem

Managed Postgres poolers/proxies can drop idle or in-flight connections (rebalancing, failover, idle-connection reaping); flaky networks do the same. When a connection dies mid-query, pg surfaces:

  • Connection terminated unexpectedly / Connection terminated
  • ECONNRESET / EPIPE socket errors
  • 57P01 (terminating connection due to administrator command)

and the request fails with a 500 even though the statement never ran anywhere.

Repro: kill the Postgres backend mid-query → the caller gets a 500 with Connection terminated unexpectedly.

Fix

  • Set keepAlive: true on the pg.Pool so dead peers are detected promptly and idle connections are less likely to be reaped by middleboxes.
  • In the pool's simple-query path (query()), retry once on a fresh client when the failure is a connection-drop error, via a new exported isConnectionDropError(err) helper. Any other error still throws immediately.

The retry is deliberately single-shot and limited to the pool-level query() path, where each attempt checks out a fresh client from the pool (the dropped client is discarded by pg), so the retry never reuses a dead connection. Transactions (withPgTransaction) are untouched — replaying those is not reuse-safe.

Tests

  • New unit test covering isConnectionDropError (positive shapes + non-drop errors + non-object inputs).
  • Existing pg-pool, pg-ca-options, and persistence-init-retry suites pass; tsc --noEmit clean.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Managed Postgres poolers/proxies can drop idle or in-flight connections
(rebalancing, failover, idle-connection reaping). When that happens
mid-query, pg surfaces 'Connection terminated unexpectedly' /
'Connection terminated', ECONNRESET/EPIPE socket errors, or 57P01
(terminating connection due to administrator command), and the request
fails with a 500 even though the statement never ran anywhere.

Repro: kill the Postgres backend mid-query; the caller gets a 500 with
'Connection terminated unexpectedly'.

Fix:
- set keepAlive: true on the pg.Pool so dead peers are detected and
  idle connections are less likely to be reaped by middleboxes
- in the pool's simple-query path, retry once on a fresh client when
  the failure is a connection-drop error (new isConnectionDropError
  helper); anything else still throws immediately

The retry is deliberately single-shot and limited to the pool-level
query() path, where a checkout from the pool yields a fresh client.
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.

1 participant