A managed database platform sees connection exhaustion when customers run serverless functions against it. Why does this happen and what is the fix?
Show the full answer Hide the answer
Why it happens
A traditional application server holds a small pool of long-lived connections and multiplexes many requests across them. A serverless function is the opposite: many short-lived instances, each wanting its own connection, with no coordination between them.
A thousand concurrent invocations can attempt a thousand connections. Databases with a per-connection process or thread model have a hard practical ceiling far below that, and each connection costs memory whether or not it is executing a query.
The failure is abrupt: connections are fine, then they are exhausted, and the database rejects everything including the healthy traffic.
The fix
- An external connection pooler between the functions and the database, multiplexing many client connections onto few server connections. This is the essential component and its absence is the actual cause.
- Transaction-level pooling rather than session-level, which allows far higher multiplexing — at the cost of losing session state: prepared statements, temporary tables, session variables and advisory locks stop working as expected. That constraint has to be communicated, because it breaks code that worked before.
- A hard connection cap per tenant, so one customer's runaway function count cannot exhaust a shared pooler.
- Short statement timeouts, since a slow query now holds a pooled connection that many clients are waiting for.
The deeper architectural point
Serverless moves the bottleneck rather than removing it. It solves compute elasticity and creates a connection-fan-in problem at every stateful dependency — databases, caches, third-party APIs with rate limits. Anything with a per-connection or per-client cost needs an intermediary.
The general shape of the fix is the same everywhere: an intermediary that converts many ephemeral clients into few persistent ones, whether that is a connection pooler, a queue, or a shared gateway holding upstream connections.
The alternative worth considering
For some workloads the right answer is not pooling but a data API over HTTP, where the stateless request model matches the stateless compute model and connection management is the platform's problem rather than the customer's. That is a different product decision with different consistency and capability trade-offs, and it sidesteps the problem rather than solving it.