Stop guessing when your database is about to run out of connections.
You’ve seen it before: an app starts failing with "sorry, too many clients already", and you only notice when users complain. By then, the database is saturated, and even your admin tools can’t connect. pgwd (Postgres Watch Dog) is a small Go CLI that watches your connection counts and alerts you before you hit the limit—and when you can’t connect at all.
The problem
PostgreSQL has a max_connections limit. When you exceed it:
- New connections are rejected with FATAL: sorry, too many clients already (SQLSTATE 53300).
- If your app uses a superuser (or a role that can use all slots), even DBA access can be blocked unless you’ve reserved slots with
superuser_reserved_connections.
Without something watching connection usage, you only find out when things are already broken.

How pgwd fits in: it watches your Postgres and pushes alerts to Slack and/or Loki when thresholds are exceeded or the connection fails.
The idea: watch and alert
pgwd connects to your Postgres (directly or via Kubernetes), reads connection stats from pg_stat_activity, and sends alerts to Slack and/or Loki when:
-
Total or active connections cross a threshold (e.g. 80% of
max_connections). - Idle or stale connections exceed limits (useful for spotting connection leaks).
- The connection fails—including "too many clients"—so you get an urgent notification even when pgwd itself can’t connect.
So you get notified when you’re approaching the limit, and again when the instance is already saturated.

When the DB is saturated, pgwd sends an urgent alert like this to your notifiers.
pgwd in action
Minimal setup (one-shot from cron)
# Alert when total connections >= 80% of server max_connections (default)
pgwd -db-url "postgres://user:pass@localhost:5432/mydb" \
-slack-webhook "https://hooks.slack.com/services/..."
No need to set thresholds if you’re fine with 80%: pgwd reads max_connections from the server and applies a default percentage.
Daemon mode (continuous watch)
export PGWD_DB_URL="postgres://localhost:5432/mydb"
export PGWD_SLACK_WEBHOOK="https://hooks.slack.com/..."
export PGWD_INTERVAL=60
pgwd
# Runs every 60 seconds; exit with SIGTERM.
Catch connection leaks (stale connections)
pgwd -db-url "postgres://..." -slack-webhook "https://..." \
-stale-age 600 -threshold-stale 1
Alerts when any connection has been open longer than 10 minutes—handy for spotting leaks or long-running transactions.
Postgres in Kubernetes
pgwd -kube-postgres default/svc/postgres \
-db-url "postgres://user:DISCOVER_MY_PASSWORD@localhost:5432/mydb" \
-slack-webhook "https://..."
pgwd runs kubectl port-forward, can read the password from the pod’s environment, and connects to localhost. Alerts include cluster/namespace/service context.
When things go wrong
If the database is unreachable or returns "too many clients", pgwd always sends an urgent alert to your notifiers (when configured)—no extra flag needed. So even in the worst case, you get a Slack/Loki message instead of silence.
Try it
-
Install:
go install github.com/hrodrig/pgwd@latest - Repo and docs: github.com/hrodrig/pgwd
-
Releases: Releases (binaries, Docker image
ghcr.io/hrodrig/pgwd)
One-shot, daemon, or cron—with Slack and/or Loki you can stop flying blind on connection usage and get ahead of "too many clients" before it hits production.
Disclosure: This post was drafted with AI assistance and reviewed by the author.
Top comments (0)