insightral for Supabase — spot what pgBouncer hides
Supabase routes every connection through pgBouncer in transaction pooling mode. That choice makes connection management effortless, and it also makes a handful of Postgres problems invisible to the usual monitoring tools. insightral connects directly to your Supabase Postgres endpoint — bypassing the pooler — and surfaces those problems before they become incidents.
Read-only role. No data leaves your infrastructure.
What transaction pooling skews in pg_stat_activity
In transaction pooling mode, a server connection is held only for the duration of a transaction, then returned to the pool. From Postgres's perspective, many short-lived application threads share a much smaller set of backend processes. The side effect: pg_stat_activity shows fewer rows than you have application threads, and idle sessions in the pool appear as idle rather than idle in transaction.
The consequence: idle-in-transaction sessions — the kind that hold row locks and block autovacuum — do not always register correctly when pooler-mediated traffic is involved. insightral connects to the direct Postgres port (5432 or the session-mode Supavisor port) rather than the pgBouncer port (6543) so it reads raw backend state. It detects genuine idle-in-transaction sessions, long-running transaction pressure, and connection saturation at the Postgres layer — not the pooler layer.
# Use the direct connection string from Supabase project settings
INSIGHTRAL_PG_DSN='postgres://readonly:***@db.<ref>.supabase.co:5432/postgres?sslmode=require'
Not the pooler URL (port 6543) — use the direct URL (port 5432).
Realtime subscription row-count cost
Supabase Realtime uses a logical replication slot to stream row-level changes to subscribers. Every active subscription adds a consumer to that slot. If subscriber throughput drops — a client goes offline, a flaky WebSocket reconnects slowly — the replication slot accumulates lag. Postgres holds WAL on disk to satisfy the lagging slot. If that lag grows unchecked, it can fill your allocated disk before the next time you look at a dashboard.
insightral's replication slot lag rule reads pg_replication_slots and fires when any slot exceeds a configurable byte threshold. On Supabase, the relevant slot is typically named supabase_realtime_replication_slot. A single slow subscriber can grow that lag to gigabytes — silently, until the disk alarm fires.
- Rule fires when slot lag exceeds 500 MB (configurable via
INSIGHTRAL_SLOT_LAG_WARN_MB) - Finding includes slot name, bytes retained, and oldest inactive consumer
- Slack alert links directly to the Supabase Realtime dashboard for remediation
RLS policy overhead detection
Row-level security is Supabase's primary multi-tenancy mechanism and it works correctly until a policy is written in a way that prevents the planner from using an index. The canonical failure mode is a policy that compares auth.uid() against a column that has no supporting index, causing a sequential scan on every request that touches that table.
insightral surfaces this via two overlapping signals. The high seq-scan ratio rule flags tables where sequential scans dominate index scans in pg_stat_user_tables. The slow-query rule (via pg_stat_statements) catches queries with high mean execution time on RLS-gated tables. Between the two signals, most RLS index omissions appear within the first 5-minute poll after they start accumulating scan counts.
The finding includes the table name, the current scan ratio, and a note to verify that the column referenced in the policy carries a B-tree index. The finding text explains what RLS is and why it matters, so you do not need to brief your team before handing it off.
Connect in 60 seconds
Use the direct Supabase connection string (port 5432, not the pooler port 6543). Create a read-only Postgres role — the onboarding wizard provides the exact GRANT SQL. insightral connects, runs its ruleset, and posts to Slack if it finds anything worth your attention.