From d43ff0f2a9fb25ffd09e0f1533d16223f5d07a02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ask=20Bj=C3=B8rn=20Hansen?= Date: Sun, 30 Nov 2025 09:35:55 -0800 Subject: [PATCH] fix(pgdb): align pool defaults with pgxpool Change MaxConns default from 25 to 4 to match pgxpool defaults. This ensures consistent behavior between DATABASE_URI and config file modes, and removes the warning log when using URI mode. Defaults now reference: https://pkg.go.dev/github.com/jackc/pgx/v5/pgxpool#Config --- database/pgdb/CLAUDE.md | 8 ++++-- database/pgdb/pool.go | 50 +++++++++++++++++++------------------- database/pgdb/pool_test.go | 4 +-- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/database/pgdb/CLAUDE.md b/database/pgdb/CLAUDE.md index b577606..ef2e72e 100644 --- a/database/pgdb/CLAUDE.md +++ b/database/pgdb/CLAUDE.md @@ -75,13 +75,17 @@ sslmode: prefer ### PoolOptions +Defaults match [pgxpool defaults](https://pkg.go.dev/github.com/jackc/pgx/v5/pgxpool#Config): + - `ConfigFiles` - List of config file paths to search (default: `database.yaml`, `/vault/secrets/database.yaml`) - `MinConns` - Minimum connections (default: 0) -- `MaxConns` - Maximum connections (default: 25) +- `MaxConns` - Maximum connections (default: 4) - `MaxConnLifetime` - Connection lifetime (default: 1 hour) - `MaxConnIdleTime` - Idle timeout (default: 30 minutes) - `HealthCheckPeriod` - Health check interval (default: 1 minute) +For higher connection limits, set via `PoolOptions` or URI query parameter `?pool_max_conns=25`. + ### PostgreSQL Config Fields - `host` - Database host (required) @@ -108,7 +112,7 @@ Pool settings can be included in the URI query string: - `pool_max_conn_lifetime`, `pool_max_conn_idle_time` - `pool_health_check_period` -When using `DATABASE_URI`, `PoolOptions` are ignored and all settings come from the URI. +When using `DATABASE_URI`, pool settings come from the URI. Since `PoolOptions` defaults match pgxpool defaults, behavior is consistent whether using URI or config files. Example with CloudNativePG: ```yaml diff --git a/database/pgdb/pool.go b/database/pgdb/pool.go index 1283642..dc31cd8 100644 --- a/database/pgdb/pool.go +++ b/database/pgdb/pool.go @@ -9,42 +9,50 @@ import ( "github.com/jackc/pgx/v5/pgxpool" "go.ntppool.org/common/database" - "go.ntppool.org/common/logger" "gopkg.in/yaml.v3" ) -// PoolOptions configures pgxpool connection behavior +// PoolOptions configures pgxpool connection behavior. +// +// Default values match pgxpool defaults from github.com/jackc/pgx/v5/pgxpool. +// See: https://pkg.go.dev/github.com/jackc/pgx/v5/pgxpool#Config +// +// To customize pool settings, either: +// - Modify PoolOptions before calling OpenPool (for config file mode) +// - Use URI query parameters like ?pool_max_conns=25 (for DATABASE_URI mode) type PoolOptions struct { // ConfigFiles is a list of config file paths to search for database configuration ConfigFiles []string - // MinConns is the minimum number of connections in the pool - // Default: 0 (no minimum) + // MinConns is the minimum number of connections in the pool. + // Default: 0 (matches pgxpool default) MinConns int32 - // MaxConns is the maximum number of connections in the pool - // Default: 25 + // MaxConns is the maximum number of connections in the pool. + // Default: 4 (matches pgxpool default) + // For higher concurrency, increase via PoolOptions or URI ?pool_max_conns=N MaxConns int32 - // MaxConnLifetime is the maximum lifetime of a connection - // Default: 1 hour + // MaxConnLifetime is the maximum lifetime of a connection. + // Default: 1 hour (matches pgxpool default) MaxConnLifetime time.Duration - // MaxConnIdleTime is the maximum idle time of a connection - // Default: 30 minutes + // MaxConnIdleTime is the maximum idle time of a connection. + // Default: 30 minutes (matches pgxpool default) MaxConnIdleTime time.Duration - // HealthCheckPeriod is how often to check connection health - // Default: 1 minute + // HealthCheckPeriod is how often to check connection health. + // Default: 1 minute (matches pgxpool default) HealthCheckPeriod time.Duration } -// DefaultPoolOptions returns sensible defaults for pgxpool +// DefaultPoolOptions returns defaults matching pgxpool. +// See https://pkg.go.dev/github.com/jackc/pgx/v5/pgxpool#Config for pgxpool defaults. func DefaultPoolOptions() PoolOptions { return PoolOptions{ ConfigFiles: GetConfigFiles(), MinConns: 0, - MaxConns: 25, + MaxConns: 4, MaxConnLifetime: time.Hour, MaxConnIdleTime: 30 * time.Minute, HealthCheckPeriod: time.Minute, @@ -63,8 +71,6 @@ func DefaultPoolOptions() PoolOptions { // can be specified in the URI query string and PoolOptions are ignored. // When using config files, PoolOptions are applied. func OpenPool(ctx context.Context, options PoolOptions) (*pgxpool.Pool, error) { - log := logger.FromContext(ctx) - // Validate PoolOptions if options.MaxConns <= 0 { return nil, fmt.Errorf("pgdb: MaxConns must be positive, got: %d", options.MaxConns) @@ -80,20 +86,14 @@ func OpenPool(ctx context.Context, options PoolOptions) (*pgxpool.Pool, error) { var err error // Check DATABASE_URI environment variable first (highest priority) + // When using DATABASE_URI, pool settings come from URI query parameters + // (e.g., ?pool_max_conns=25). PoolOptions are not applied since our defaults + // match pgxpool defaults. if uri := os.Getenv("DATABASE_URI"); uri != "" { poolConfig, err = pgxpool.ParseConfig(uri) if err != nil { return nil, fmt.Errorf("failed to parse DATABASE_URI: %w", err) } - - // Log when PoolOptions differ from defaults (they will be ignored) - defaults := DefaultPoolOptions() - if options.MaxConns != defaults.MaxConns || options.MinConns != defaults.MinConns { - log.WarnContext(ctx, "DATABASE_URI is set; PoolOptions are ignored (use URI query parameters for pool settings)", - "ignored_max_conns", options.MaxConns, - "ignored_min_conns", options.MinConns, - ) - } } else { // Fall back to config file approach pgCfg, _, err := FindConfig(options.ConfigFiles) diff --git a/database/pgdb/pool_test.go b/database/pgdb/pool_test.go index efd14e1..a872e6f 100644 --- a/database/pgdb/pool_test.go +++ b/database/pgdb/pool_test.go @@ -115,8 +115,8 @@ func TestDefaultPoolOptions(t *testing.T) { if opts.MinConns != 0 { t.Errorf("Expected MinConns=0, got %d", opts.MinConns) } - if opts.MaxConns != 25 { - t.Errorf("Expected MaxConns=25, got %d", opts.MaxConns) + if opts.MaxConns != 4 { + t.Errorf("Expected MaxConns=4 (pgxpool default), got %d", opts.MaxConns) } if opts.MaxConnLifetime != time.Hour { t.Errorf("Expected MaxConnLifetime=1h, got %v", opts.MaxConnLifetime)