Our Dashboard Looked Fine. The Database Was Out of Connections.
At 50 conversations a week, one database feels like enough for everyone. At thousands, every service that touches it becomes a tenant fighting for the same front door. We learned this the hard way. The dashboards broke first. The CPU graph looked fine. That mismatch sent us down the wrong path for longer than it should have. How the system behaved at low volume We run a conversation intelligence…
At first, everything appeared fine on the dashboard. Audio was transcribed, audited and displayed in the dashboards for team leads and QA managers. The system ran on a shared Postgres instance with each service connecting to it and opening a connection pool. At modest volume, this seemed efficient, with idle pools and fast query responses.
However, as conversation volume increased, more worker tasks were added, each bringing its own connection pool. The database hit a hard connection ceiling, refusing new connections. Dashboard crashes and errors started appearing, but monitoring tools couldn't query the database either. The login page still loaded, making the failure seem localized.
The root cause was "pool stacking," where every service reserved connections regardless of use, causing the database to act like a parking lot. To prevent this, connection budgets per service should be set, with hard caps negotiated against the shared budget. A pooling layer in front of Postgres can also help share fewer database slots among many application connections.
Every service that processes customer conversations, such as a BPO platform, CRM, EdTech company, or workforce management tool, faces this issue. The key takeaway is that connection slots are a hidden capacity limit that only surfaces when compute scales faster than connection planning.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.