Skip to content
Connection Pool Configuration

Connection Pool Configuration

A job queue system opens many concurrent database connections – one per worker goroutine, plus connections for heartbeats, scheduling, and the stale lock reaper. Without proper pool configuration the database can be overwhelmed by connection churn, or workers can stall waiting for an available connection.

The simple-durable-jobs library exposes Go’s database/sql pool settings through a clean option-based API so you can tune connection usage to match your workload.

Creating Storage with Pool Configuration

Using a Preset

The fastest way to get started is to pick a preset that matches your deployment profile:

storage, err := jobs.NewGormStorageWithPool(db, jobs.HighConcurrencyPoolConfig())
if err != nil {
    log.Fatal(err)
}

Customizing Individual Settings

You can mix and match individual pool options:

storage, err := jobs.NewGormStorageWithPool(db,
    jobs.MaxOpenConns(50),
    jobs.MaxIdleConns(20),
    jobs.ConnMaxLifetime(10 * time.Minute),
    jobs.ConnMaxIdleTime(2 * time.Minute),
)
if err != nil {
    log.Fatal(err)
}

Configuring an Existing Database

If you already have a *gorm.DB that you opened elsewhere, you can apply pool settings to it directly and then create storage normally:

err := jobs.ConfigurePool(db, jobs.MaxOpenConns(100))
if err != nil {
    log.Fatal(err)
}
storage := jobs.NewGormStorage(db)

Available Presets

Each preset returns a PoolConfig struct with values tuned for a specific deployment scenario:

PresetMaxOpenMaxIdleMaxLifetimeMaxIdleTimeUse Case
DefaultPoolConfig()25105 min1 minGeneral purpose
HighConcurrencyPoolConfig()1002510 min2 min50+ workers, high throughput
LowLatencyPoolConfig()504015 min5 minLatency-sensitive workloads
ResourceConstrainedPoolConfig()1053 min30 sLimited DB resources

DefaultPoolConfig

Suitable for most workloads. Allows up to 25 concurrent database connections with 10 kept warm in the idle pool. Connections are recycled every 5 minutes to prevent stale connections from accumulating.

HighConcurrencyPoolConfig

Designed for deployments running 50 or more worker goroutines. Opens up to 100 connections and keeps 25 idle. Longer lifetimes reduce the overhead of re-establishing connections under sustained load.

LowLatencyPoolConfig

Optimized for workloads where connection acquisition time matters. Keeps 40 of 50 connections warm in the idle pool, so most dequeue and completion operations hit a pre-established connection. Longer idle times prevent unnecessary teardown.

ResourceConstrainedPoolConfig

Use this when your database has strict connection limits (for example, a small managed database instance or a serverless database with a low connection cap). Limits the pool to 10 open and 5 idle connections with aggressive recycling.

Individual Options

Each option sets a single field on the underlying PoolConfig:

OptionDescription
MaxOpenConns(n int)Maximum number of open database connections. Set to 0 for unlimited (not recommended for production).
MaxIdleConns(n int)Maximum number of idle connections kept in the pool. Should be less than or equal to MaxOpenConns.
ConnMaxLifetime(d time.Duration)Maximum amount of time a connection can be reused before it is closed and replaced. Set to 0 for no limit (not recommended).
ConnMaxIdleTime(d time.Duration)Maximum amount of time a connection can sit idle before it is closed. Set to 0 for no limit.

Choosing the Right Configuration

Here are guidelines to help you pick the right settings:

Match MaxOpenConns to Worker Concurrency

Every worker goroutine may hold a database connection while processing a job. Add connections for heartbeats, the stale lock reaper, the scheduler, and the dequeue poll loop. A safe starting point is:

MaxOpenConns >= total worker concurrency + 10

For example, if you run three queues with concurrency 20, 10, and 5 (total 35), set MaxOpenConns to at least 45.

Size the Idle Pool at 25-50% of MaxOpenConns

Idle connections avoid the latency of establishing a new TCP connection and TLS handshake. For typical workloads, keeping 25-50% of connections warm provides a good balance between responsiveness and resource usage.

Set ConnMaxLifetime to 5-15 Minutes

Recycling connections periodically prevents issues with stale TCP sessions, load-balancer idle timeouts, and DNS changes in cloud environments. Five minutes is a good default; increase to 10-15 minutes under sustained high throughput to reduce churn.

Respect Cloud Database Limits

Many managed database services impose connection limits (for example, a small PostgreSQL instance may allow only 100 connections shared across all applications). Use ResourceConstrainedPoolConfig or manually set MaxOpenConns to stay within your quota. Remember that each application replica has its own pool, so divide the limit across replicas.