intermediate 2 min answer

A managed database platform sees connection exhaustion when customers run serverless functions against it. Why does this happen and what is the fix?

supabaseconnection-poolingserverlessdatabasepgbouncer
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.