@@ -25,6 +25,7 @@ import (
2525 "io"
2626 "net"
2727 "strconv"
28+ "time"
2829
2930 "github.com/jackc/pgx/v5"
3031 "github.com/jackc/pgx/v5/multitracer"
@@ -54,7 +55,10 @@ type (
5455
5556 debug bool
5657
57- poolSize int32
58+ poolSize int32
59+ minPoolSize int32
60+ maxConnIdleTime time.Duration
61+ maxConnLifetime time.Duration
5862
5963 tlsConfig * tls.Config
6064
@@ -135,12 +139,53 @@ func WithTLS(certs []*x509.Certificate) Option {
135139 }
136140}
137141
142+ // WithPoolSize sets the maximum number of connections the pool will
143+ // open. It maps to pgxpool.Config.MaxConns.
138144func WithPoolSize (i int32 ) Option {
139145 return func (c * Client ) {
140146 c .poolSize = i
141147 }
142148}
143149
150+ // WithMinPoolSize sets the minimum number of connections the pool
151+ // keeps warm. It maps to pgxpool.Config.MinConns. Keeping a non-zero
152+ // floor avoids paying the TCP + TLS + PostgreSQL startup handshake
153+ // cost on the first acquire after an idle period, which otherwise
154+ // shows up as tail latency on pgxpool_acquire_duration_seconds.
155+ //
156+ // When unset, the client defaults to 1 (historical behaviour).
157+ func WithMinPoolSize (i int32 ) Option {
158+ return func (c * Client ) {
159+ c .minPoolSize = i
160+ }
161+ }
162+
163+ // WithMaxConnIdleTime sets how long a connection can be idle before
164+ // it is eligible to be destroyed. It maps to
165+ // pgxpool.Config.MaxConnIdleTime. A zero value leaves the pgx default
166+ // (30 minutes) in place.
167+ //
168+ // Increasing this value reduces connection churn for bursty
169+ // workloads, at the cost of holding idle connections longer.
170+ func WithMaxConnIdleTime (d time.Duration ) Option {
171+ return func (c * Client ) {
172+ c .maxConnIdleTime = d
173+ }
174+ }
175+
176+ // WithMaxConnLifetime sets the maximum lifetime of a connection
177+ // before it is recycled. It maps to pgxpool.Config.MaxConnLifetime.
178+ // A zero value leaves the pgx default (1 hour) in place.
179+ //
180+ // Increasing this value reduces connection churn for long-lived
181+ // processes, at the cost of keeping the same backend connection
182+ // open for longer.
183+ func WithMaxConnLifetime (d time.Duration ) Option {
184+ return func (c * Client ) {
185+ c .maxConnLifetime = d
186+ }
187+ }
188+
144189// WithTracerProvider configures OpenTelemetry tracing with the
145190// provided tracer provider.
146191func WithTracerProvider (tp trace.TracerProvider ) Option {
@@ -182,6 +227,7 @@ func NewClient(options ...Option) (*Client, error) {
182227 user : "postgres" ,
183228 database : "postgres" ,
184229 poolSize : 10 ,
230+ minPoolSize : 1 ,
185231 logger : log .NewLogger (log .WithOutput (io .Discard )),
186232 tracerProvider : otel .GetTracerProvider (),
187233 registerer : prometheus .DefaultRegisterer ,
@@ -208,8 +254,14 @@ func NewClient(options ...Option) (*Client, error) {
208254 config .ConnConfig .Password = c .password
209255 config .ConnConfig .Database = c .database
210256 config .ConnConfig .TLSConfig = c .tlsConfig
211- config .MinConns = 1
212- config .MaxConns = int32 (c .poolSize )
257+ config .MinConns = c .minPoolSize
258+ config .MaxConns = c .poolSize
259+ if c .maxConnIdleTime > 0 {
260+ config .MaxConnIdleTime = c .maxConnIdleTime
261+ }
262+ if c .maxConnLifetime > 0 {
263+ config .MaxConnLifetime = c .maxConnLifetime
264+ }
213265
214266 c .tracer = c .tracerProvider .Tracer (
215267 tracerName ,
0 commit comments