Skip to main content

PostgreSQL

PostgreSQL is the recommended production database backend. It provides connection pooling, ACID transactions, and high-availability via streaming replication.

Supported versions

PostgreSQL 14 and later.

Configuration

db:
dsn: "postgres://talos:secret@db:5432/talos?sslmode=require&max_conns=25&max_conn_lifetime=5m"

Or via environment variable:

export TALOS_DB_DSN="postgres://talos:secret@db:5432/talos?sslmode=require&max_conns=25&max_conn_lifetime=5m"

DSN format

postgres://user:password@host:port/dbname?param=value&param=value

Both postgres:// and postgresql:// schemes are accepted.

DSN parameters

Connection pool parameters

Pool parameters are parsed from the DSN query string and removed before the DSN is passed to the database driver.

ParameterTypeDefaultDescription
max_connsinteger25Maximum number of open connections in the pool
max_idle_connsinteger5Maximum number of idle connections (must be ≤ max_conns)
max_conn_lifetimeduration30mMaximum age of a connection before it is closed and replaced
max_conn_idle_timeduration10mMaximum time a connection can sit idle before it is closed
pool_modestringstandardPool implementation: standard or advanced (see below)

Duration values use Go duration syntax: 5m (5 minutes), 1h (1 hour), 30s (30 seconds).

Talos sets non-zero defaults for max_conn_lifetime and max_conn_idle_time so connections are recycled through load balancers, DNS rotation, and PostgreSQL tcp_keepalives_*. Setting either to 0 disables the recycle and is not recommended outside development.

PostgreSQL driver parameters

These parameters are passed through to the underlying PostgreSQL driver (pgx).

ParameterDescriptionRecommended
sslmodeTLS mode (disable, require, verify-ca, verify-full)verify-full
sslrootcertPath to CA certificate file
sslcertPath to client certificate file (for mTLS)
sslkeyPath to client private key file (for mTLS)
connect_timeoutConnection timeout in seconds10
application_nameApplication name reported to PostgreSQL

Connection pooling

Talos supports two pool modes for PostgreSQL, controlled by the pool_mode DSN parameter.

Standard mode (default)

Uses Go's database/sql connection pool with the pgx driver. This is the default and works with all tooling.

db:
dsn: "postgres://talos:secret@db:5432/talos?max_conns=25&max_idle_conns=5&max_conn_lifetime=5m&max_conn_idle_time=1m"

Pool behavior:

  • Connections are created on demand up to max_conns
  • Idle connections are kept up to max_idle_conns
  • Connections older than max_conn_lifetime are closed and replaced
  • Connections idle longer than max_conn_idle_time are closed

Advanced mode

Uses native pgxpool for high-availability deployments. Provides built-in health checks and is optimized for Kubernetes and cloud environments.

db:
dsn: "postgres://talos:secret@db:5432/talos?pool_mode=advanced&pool_max_conns=50&pool_min_conns=2&pool_max_conn_lifetime=30m&pool_max_conn_idle_time=10m"

In advanced mode, pool sizing is configured through pgxpool's native parameters parsed from the DSN. The max_conns, max_idle_conns, max_conn_lifetime, and max_conn_idle_time parameters are ignored — use the pool_* equivalents instead.

pgxpool parameterDefaultDescription
pool_max_conns4 × runtime.NumCPU()Maximum size of the pgxpool connection pool
pool_min_conns0Minimum number of connections kept open
pool_max_conn_lifetime1hMaximum age of a connection before it is replaced
pool_max_conn_idle_time30mMaximum idle time before an idle connection is closed
pool_health_check_period1mInterval between background health checks

Talos exposes the pgxpool through Go's database/sql interface. The wrapper's SetMaxIdleConns is forced to 0 so that database/sql never holds connections idle on top of pgxpool — the pgxpool layer is the single source of truth for pool sizing in advanced mode.

Use advanced mode when:

  • Running in Kubernetes with connection health checks
  • Using cloud-managed PostgreSQL (RDS, Cloud SQL, AlloyDB) with aggressive connection recycling
  • Deploying with PgBouncer and needing precise pool control

Pool sizing

Start with 25 connections per instance. The total pool across all instances must stay below PostgreSQL's max_connections (default: 100).

Deploymentmax_connsNotes
Single instance25Good starting point
3 instances25 each75 total — within default max_connections
5+ instances1520 eachUse PgBouncer to multiplex connections

For large deployments, place PgBouncer between Talos and PostgreSQL. PgBouncer multiplexes many application connections over fewer database connections, allowing you to scale beyond PostgreSQL's connection limit.

Migrations

talos-commercial migrate up --database "postgres://talos:secret@db:5432/talos"

TLS / SSL

Use the sslmode parameter in the DSN for encrypted database connections:

db:
dsn: "postgres://talos:secret@db:5432/talos?sslmode=verify-full&sslrootcert=/certs/ca.crt"
ModeDescription
disableNo TLS
requireTLS without certificate verification
verify-caTLS with CA verification
verify-fullTLS with CA and hostname verification (recommended)

For mutual TLS (mTLS), provide both client certificate and key:

db:
dsn: "postgres://talos:secret@db:5432/talos?sslmode=verify-full&sslrootcert=/certs/ca.crt&sslcert=/certs/client.crt&sslkey=/certs/client.key"

Example DSNs

Development:

postgres://talos:secret@localhost:5432/talos?sslmode=disable

Production with standard pooling:

postgres://talos:secret@db:5432/talos?sslmode=verify-full&sslrootcert=/certs/ca.crt&max_conns=25&max_idle_conns=5&max_conn_lifetime=5m&max_conn_idle_time=1m

Production with advanced pooling (Kubernetes):

postgres://talos:secret@db:5432/talos?sslmode=verify-full&sslrootcert=/certs/ca.crt&pool_mode=advanced

Behind PgBouncer:

postgres://talos:secret@pgbouncer:6432/talos?sslmode=require&max_conns=50&max_idle_conns=10&max_conn_lifetime=5m