Skip to content

Add TCP keepalive support for long queries - #1337

Closed
sonnemusk wants to merge 1 commit into
lib:masterfrom
sonnemusk:feat/tcp-keepalive
Closed

Add TCP keepalive support for long queries#1337
sonnemusk wants to merge 1 commit into
lib:masterfrom
sonnemusk:feat/tcp-keepalive

Conversation

@sonnemusk

Copy link
Copy Markdown

Summary

Implements client-side TCP keepalive support for long-running queries (e.g. behind NATs, load balancers, or Redshift), addressing #360.

This supersedes the stale approach in #999 (2020). That PR wired net.Dialer.KeepAlive only (idle and interval forced to the same value, no count). This implementation:

  • Uses libpq connection parameter names: keepalives, keepalives_idle, keepalives_interval, keepalives_count
  • Applies settings after dial on *net.TCPConn via SetKeepAlive / SetKeepAliveConfig (Go 1.23+), so idle, interval, and count can be set independently
  • Works with any dialer that returns a TCP connection (or a NetConn() wrapper such as *tls.Conn)
  • Leaves dialer defaults alone when parameters are omitted; ignores Unix sockets / non-TCP
  • Does not send keepalive keys as startup runtime parameters

Example:

postgres://…?keepalives=1&keepalives_idle=30&keepalives_interval=10&keepalives_count=5

Fields are also available on pq.Config.

Test plan

  • Unit tests for DSN parsing (seconds → duration, count as int, invalid values, not leaked into Runtime)
  • Unit tests for setTCPKeepalives against a real local TCP listener (enable/disable/tuning/non-TCP/no-op/NetConn unwrap)
  • CI against lib/pq

Fixes #360

Support libpq keepalive connection parameters so client-side TCP
keepalives can be enabled, disabled, or tuned for long-running queries
behind NATs and load balancers:

  keepalives=0|1
  keepalives_idle=<seconds>
  keepalives_interval=<seconds>
  keepalives_count=<n>

Settings are applied after dial via *net.TCPConn.SetKeepAlive /
SetKeepAliveConfig when the connection is TCP (including NetConn
wrappers such as *tls.Conn). Unix sockets and non-TCP dials are left
unchanged. Omitting the parameters leaves the dialer's defaults alone.

Fixes #360
@arp242 arp242 closed this Jul 26, 2026
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.

Add TcpKeepAlive

2 participants