I'm deploying an async SQLAlchemy application on Vercel using Fluid Compute, so some function instances stay warm, but Vercel can still create many instances under load. With a regular connection pool, the application is faster but can eventually consume all available connections in my Supabase database. NullPool keeps connection usage under control, but performance is noticeably worse. Supabase's shared transaction pooler allows around 200 connections, and that limit has been reached with some pool configurations but not with NullPool. Is there a practical pool configuration that preserves most of the performance benefit while limiting total connections? Would a short recycle time help, or should I use another strategy?
2 Answers
There probably isn’t a single magic setting for this. In a serverless deployment, every warm function instance can have its own SQLAlchemy pool, so even a modest pool size gets multiplied across instances. Set the pool size and overflow limit conservatively based on the maximum number of concurrent instances, rather than sizing it like a single long-running server. A short recycle time mainly replaces old connections; it does not reduce the pool’s maximum connection count and may actually create more connection churn. Since you’re already using Supabase’s pooler, also verify that the connection URL and transaction-pooling behavior match your async driver and transaction usage.
Try configuring the pool with LIFO behavior, for example `pool_use_lifo=True`, along with a sensible `pool_pre_ping` setting. LIFO tends to reuse the most recently used connections and leaves older idle connections unused during quiet periods, which can help the pool shrink toward fewer active connections. It won’t impose a hard global limit across Vercel instances, though, so keep `pool_size` and `max_overflow` small. If you need a strict application-wide connection cap, that has to be enforced by the external pooler or by using a deployment architecture with a shared connection pool; SQLAlchemy pools are local to each function instance.

That’s the main issue in my case: Vercel can start several instances instead of funneling requests through one process. NullPool avoids multiplying idle connections, while a normal pool multiplies its limits across every warm instance.