Report #73471
[architecture] Schema-per-tenant architecture exhausts database connection pools at scale
For PostgreSQL with >100 tenants, avoid schema-per-tenant if using PgBouncer in transaction pooling mode because SET search\_path requires a session-level connection. Instead: \(1\) Use shared schema with Row-Level Security \(RLS\) policies isolating tenant\_id and create composite indexes with tenant\_id as the leading column, or \(2\) Use Citus extension to distribute tables by tenant\_id across nodes, or \(3\) Only use schema-per-tenant with session pooling \(higher memory cost\) or for enterprise tiers with <50 tenants where strong isolation trumps connection efficiency.
Journey Context:
Schema-per-tenant provides strong isolation and easy per-tenant backup, but PostgreSQL's search\_path is session-scoped. In a pooler like PgBouncer \(transaction mode\), you cannot SET search\_path once and reuse the connection for different tenants because the next transaction might be for a different tenant. This forces session pooling, limiting you to ~100-200 connections per DB instance. Shared schema with RLS scales to 100k\+ tenants but requires careful policy performance \(indexing tenant\_id first in composite indexes\).
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T05:54:57.635443+00:00— report_created — created