Lesson 21 · PostgreSQL in Go
pgx & the connection pool
How your Go services actually connect to Postgres.
Your win: explain what pgx is, why a connection pool matters, and how ours is configured — the foundation for the RLS trace that finishes this course.
pgx: the driver our repo uses
pgx (jackc/pgx) is a Go PostgreSQL driver and
toolkit. It speaks the Postgres wire protocol directly — not through
database/sql — and pairs with pgtype for rich types (Lesson 2).
⚠️ Our repo is mostly v4 (v4.18) with a few v5 files; don't mix their
Tx/Row types across a boundary.1
Why a connection pool
Opening a connection (TCP + TLS + auth + session setup) for every query is slow. A
connection pool (pgxpool) keeps a set of live
connections and lends one out per query, returning it after. That bounds load on Postgres
and makes "get a connection" nearly free.2
// NewPool: parse config → connect, with retry
poolconfig, _ := pgxpool.ParseConfig(connStr)
poolconfig.MaxConns = cfg.MaxConns // cap on concurrent connections
poolconfig.MaxConnIdleTime = cfg.MaxConnIdleTime
poolconfig.BeforeAcquire = setPostgres[...] // ← the tenant hook (Lesson 24)
pool, _ := pgxpool.ConnectConfig(ctx, poolconfig)
MaxConns caps concurrency — too low starves the app, too high overwhelms
Postgres (each connection is a backend process). MaxConnIdleTime reaps idle
connections. These come from a per-DB PostgresDatabaseConfig (each service's
database gets its own pool).
BeforeAcquire = setPostgres: a
hook that runs on every connection checkout to stamp the tenant onto the session
— which is how RLS multi-tenancy works (Lesson 24). The pool isn't just performance; it's
where per-request security gets injected.
pgx + pgxpool
The driver README/wiki and the pool package docs (ParseConfig, ConnectConfig, pool sizing, hooks).
Check yourself (from memory)
Q1. A connection pool exists to…
MaxConns caps concurrency.
Q2. Our services use which Go driver?
pgtype. Not database/sql.
Q3. pgxpool's MaxConns setting…
pgtype), not via
database/sql. A connection POOL (pgxpool) keeps live connections
and lends one per query — connecting each time is expensive; the pool bounds DB load and
makes acquire fast. Ours: database.NewPool → pgxpool.ParseConfig
+ ConnectConfig, with MaxConns and MaxConnIdleTime
from a per-DB config; non-local uses the Cloud SQL Go Connector; a BeforeAcquire
hook stamps the tenant on each checkout (Lesson 24).1. jackc/pgx.
2. pgx/v4/pgxpool.