Operate2 min read

Configure PgBouncer with Helm

Enable Web-only PgBouncer transaction pooling for split Helm deployments while retaining direct role connections.

Prerequisites

Use runtime.mode: split, calculate the backend connection budget, and configure a direct database path for migration and non-Web roles.

Prepare the configuration

Enable pgbouncer, set reviewed client/backend pool limits, supply credentials through the existing Secret, and configure private CA verification when required. Web receives the pooled URL; migration, Scheduler, workers, and Status Projector retain direct URLs.

Create values.pgbouncer.yaml to enable and configure PgBouncer pooling:

yaml
pgbouncer:
  enabled: true
  replicas: 2
  port: 6432
  poolMode: transaction
  maxClientConnections: 1000
  defaultPoolSize: 10
  reservePoolSize: 5
  maxPreparedStatements: 100
  podDisruptionBudget:
    enabled: true
    minAvailable: 1
  resources:
    requests:
      cpu: 50m
      memory: 64Mi
    limits:
      cpu: 500m
      memory: 256Mi
  securityContext:
    allowPrivilegeEscalation: false
    capabilities:
      drop: [ALL]
    runAsNonRoot: true
    runAsUser: 70
    runAsGroup: 70
    readOnlyRootFilesystem: true

Deploy PgBouncer

Lint/render and inspect the PgBouncer Deployment, Service, Secret references, NetworkPolicy, PDB, and Web database environment. Ensure the migration Job never targets port 6432.

Apply the configuration with Helm:

sh
helm upgrade --install opsknight deploy/kubernetes/helm/opsknight \
  --namespace opsknight \
  -f values.production.yaml \
  -f values.split.yaml \
  -f values.pgbouncer.yaml

Watch rollout readiness across PgBouncer and Web pods:

sh
kubectl -n opsknight rollout status deployment/opsknight-pgbouncer
kubectl -n opsknight rollout status deployment/opsknight-web

Verify pooling

Confirm the migration hook succeeds directly, PgBouncer and Web are Ready, and a synthetic incident completes. Observe client wait, backend pool use, PostgreSQL connections, and Web readiness under representative traffic.

Operate it in production

Alert on client wait, server-pool saturation, TLS/auth failure, restarts, and direct database exhaustion. Keep reserve for migrations, workers, monitoring, and emergency access.

Troubleshooting

PgBouncer Pod fails: inspect structured endpoint/credentials, Secret keys, DNS/network, TLS CA, and configuration logs.

Migration fails with pooling enabled: correct the Job's direct URL; never migrate through transaction pooling.

Clients wait despite high client limit: backend/database capacity is exhausted; tune the backend pool or database rather than only increasing clients.

Change or remove PgBouncer

First validate the direct Web connection budget, update Web to direct PostgreSQL, roll and verify it, then disable PgBouncer. Do not remove the Service while Web still targets it.

Next steps

Last updated for v2.1.0

Edit this page on GitHub