ReviewOS

stacks/bun-query-builder

expose connection pool config in setConfig (DatabaseConfig)

#1014
Closed glennmichael123 opened this 2 months ago ·
2 months ago

TL;DR

setConfig({ database: { ... } }) accepts host/port/credentials but no pool-tuning options. Downstream consumers (Stacks via @stacksjs/database — see stacksjs/stacks#1876 D-3) have no path to set pool size, idle timeout, or retry-on-disconnect, so a long-running server hits "max connections" with no actionable knob.

Filing as a tracker so consumers know the API surface is on the roadmap.

Today

```ts import { setConfig } from 'bun-query-builder'

setConfig({ dialect: 'postgres', database: { database: 'app', host: 'localhost', port: 5432, username: 'app', password: '...', }, }) ```

There's no way to tune the underlying Bun SQL pool. Bun's drivers (`Bun.SQL` etc.) accept pool options natively — they're just not threaded through the qb config layer.

Proposed shape

Add an optional `pool` block to `DatabaseConfig`:

```ts export interface DatabaseConfig { database: string username: string password: string host: string url?: string port: number

/** Connection pool tuning. All fields optional with sensible defaults. / pool?: { /* Max connections in the pool. Default: driver-specific (typically 10). / max?: number /* Min idle connections held open. Default: 0. / min?: number /* Idle timeout in milliseconds before a connection is released. / idleTimeoutMs?: number /* Connection-acquisition timeout in milliseconds. / acquireTimeoutMs?: number /* Whether to enable automatic reconnect on broken connection. Default: true. */ autoReconnect?: boolean } } ```

Pass through to the underlying `Bun.SQL` / `Bun.sql` constructor at connection-establish time.

Stretch: leak detection

A separate, configurable knob:

```ts pool?: { ... /**

  • When set, log a warning whenever a connection is held for
  • longer than this many milliseconds without being released.
  • Captures the stack of the original checkout to make it
  • actionable — most pool leaks come from a forgotten `await`
  • deep in a request handler. */ leakWarnAfterMs?: number } ```

This catches the common "long-running server slowly exhausts its pool" pattern in dev without forcing every user to wire up Pino-or-equivalent log mining.

Why now

Stacks tried to land a pool-config exposure in #1876 D-3 but the qb layer doesn't surface the fields — closed-loop fix needs to land here first. No urgency on shipping, just want a stable API to depend on downstream.

9 days ago

Shipped in d91259a (on main; lands in the next release).

DatabaseConfig now has an optional pool block (exported PoolConfig), threaded through to the Bun SQL driver for the network dialects:

setConfig({
  dialect: 'postgres',
  database: {
    database: 'app', host: 'localhost', port: 5432, username: 'app', password: '...',
    pool: {
      max: 20,              // → Bun SQL `max`
      idleTimeoutMs: 30000, // → `idleTimeout` (30s)
      acquireTimeoutMs: 5000, // → `connectionTimeout` (5s)
      maxLifetimeMs: 600000,  // → `maxLifetime` (600s)
    },
  },
})

Wired: max, idleTimeoutMs, acquireTimeoutMs, maxLifetimeMs — mapped from ms to Bun's native second-resolution option names by resolvePoolOptions() and passed to new SQL(connectionString, options). SQLite has no pool and ignores the block; when no pool is set, construction is unchanged.

Accepted but driver-managed (not forwarded): min and autoReconnect — Bun's SQL pool manages idle connections and reconnection itself, so these are documented forward-compat fields rather than active knobs.

Deferred: the leakWarnAfterMs stretch (connection-leak detection) — it needs checkout/release hooks Bun SQL doesn't expose at this layer; tracking separately if there's demand.

Tests added (test/config-pool.test.ts): ms→s mapping + rounding, field passthrough, forward-compat fields excluded, and that a network-dialect connection constructs with pool options without throwing. Downstream (@stacksjs/database, stacksjs/stacks#1876 D-3) can now depend on PoolConfig.

Sign in to comment on this issue.