Client Configuration
PgClientConfig options for connection, pooling, transforms, and SSL
Client Configuration
Overview
PgClientConfig defines all options for creating a PgClient. It covers connection details, pool tuning, name transforms, and custom type handling. Config can be provided directly or parsed from a connection URL.
Key Concepts
PgClientConfig Interface
export interface PgClientConfig {
// Connection
readonly url?: Redacted.Redacted | undefined
readonly host?: string | undefined
readonly port?: number | undefined
readonly path?: string | undefined
readonly ssl?: boolean | ConnectionOptions | undefined
readonly database?: string | undefined
readonly username?: string | undefined
readonly password?: Redacted.Redacted | undefined
// Custom stream (e.g., for SSH tunneling)
readonly stream?: (() => Duplex) | undefined
// Pool tuning
readonly idleTimeout?: Duration.DurationInput | undefined
readonly connectTimeout?: Duration.DurationInput | undefined
readonly maxConnections?: number | undefined
readonly minConnections?: number | undefined
readonly connectionTTL?: Duration.DurationInput | undefined
// Metadata
readonly applicationName?: string | undefined
readonly spanAttributes?: Record<string, unknown> | undefined
// Transforms
readonly transformResultNames?: ((str: string) => string) | undefined
readonly transformQueryNames?: ((str: string) => string) | undefined
readonly transformJson?: boolean | undefined
readonly types?: Pg.CustomTypesConfig | undefined
}
URL vs Individual Fields
When url is provided, the pool connects via connection string. Individual fields (host, port, database, etc.) are still checked and merged -- explicit fields take priority over URL-parsed values. After connection, config on the client reflects the merged result.
Passwords and URLs use Redacted.Redacted to prevent accidental logging:
PgClient.layer({
url: Redacted.make("postgresql://user:pass@host:5432/db")
})
Connection Pool Settings
maxConnections/minConnections- Pool size bounds (maps topg.Poolmax/min)idleTimeout- How long idle connections stay in pool (maps toidleTimeoutMillis)connectTimeout- Timeout for initial connection (default: 5 seconds). Also used as timeout for the startupSELECT 1health check.connectionTTL- Maximum lifetime of a connection (maps tomaxLifetimeSeconds)applicationName- Defaults to"@effect/sql-pg"
Name Transforms
Two transform functions enable automatic camelCase/snake_case conversion:
transformQueryNames- Applied to identifiers in SQL (column names in INSERT/UPDATE).camelToSnakemeans you write camelCase in TS, it becomes snake_case in SQL.transformResultNames- Applied to result column names.snakeToCamelmeans DB snake_case columns come back as camelCase in TS.
import { String } from "effect"
PgClient.layer({
database: "mydb",
transformQueryNames: String.camelToSnake,
transformResultNames: String.snakeToCamel
})
The transformJson option (default true) controls whether transforms are applied recursively into JSON/array values in results.
Code Examples
Minimal local connection:
const PgLive = PgClient.layer({
database: "postgres",
username: "postgres"
})
Full production config:
const PgLive = PgClient.layer({
url: Redacted.make(process.env.DATABASE_URL!),
ssl: true,
maxConnections: 20,
minConnections: 5,
idleTimeout: "30 seconds",
connectTimeout: "10 seconds",
connectionTTL: "30 minutes",
transformQueryNames: String.camelToSnake,
transformResultNames: String.snakeToCamel
})
Config from Effect Config system:
const PgLive = PgClient.layerConfig(
Config.all({
url: Config.redacted("DATABASE_URL"),
maxConnections: Config.integer("PG_MAX_CONNECTIONS").pipe(
Config.withDefault(10)
)
})
)
Related Files
src/PgClient.ts-PgClientConfiginterface andmakeconstructortest/utils.ts- Test layer examples showing URL-based and transform config