Prisma Client connection pool: configuring idle timeout and max connection age for long-running transactions
0 reputation · 05 Jun 2024, 08:42 UTC
0 reputation · 05 Jun 2024, 08:42 UTC
The Prisma Client connection pool defaults to a fixed number of connections (commonly 10), and the documented timeout option governs query execution rather than the lifecycle of pooled connections. In a service handling bursts of concurrent queries alongside occasional long-running transactions, connections can remain checked out far longer than expected, and the pool appears to have no built-in idle timeout or maximum connection age to reclaim them.
The goal is to keep the pool healthy under sustained concurrency without manual restarts: abandoned or stalled connections should eventually be released back to the pool (or to the database) instead of accumulating until new queries begin failing. Assume Prisma 5.x with PostgreSQL, though version-specific differences are a concern and should be flagged if behavior diverges.
The uncertainty is whether this is even configurable today. The pool size is set at initialization and seemingly cannot change at runtime, and no documented setting appears to cover idle eviction or connection TTL.
Is there a supported way in current Prisma versions to bound how long a pooled connection may stay idle or checked out? If not, is the intended boundary that connection lifetime must be enforced at the database or infrastructure layer instead? And does the answer differ between PostgreSQL and MySQL drivers?
32275 reputation · 05 Jun 2024, 17:58 UTC
Prisma Client (v5.x) does not currently provide native configuration options to set an idle timeout or a maximum connection age (TTL) for pooled connections. The pool_timeout parameter in the connection string governs how long the client waits to acquire a connection from the pool, not how long a connection remains open while idle.
Because the Prisma Client defers connection lifecycle management to the underlying engine and database, you must enforce these boundaries at the infrastructure or database layer. The strategy differs depending on whether you are managing a direct connection or using a proxy.
To prevent stalled or abandoned connections from accumulating, configure PostgreSQL server-side timeouts. This ensures the database terminates connections that exceed your business logic limits:
idle_in_transaction_session_timeout: Terminates any session that has been idle within an open transaction for longer than the specified time. This is the primary defense against "leaked" transactions.statement_timeout: Aborts any statement that takes more than the specified amount of time.-- Example: Terminate idle transactions after 30 seconds
ALTER SYSTEM SET idle_in_transaction_session_timeout = '30s';
SELECT pg_reload_conf();
For services with high concurrency and bursty traffic, the industry standard is to place PgBouncer between Prisma and PostgreSQL. PgBouncer provides the granular pool control Prisma lacks:
server_idle_timeout: Closes server connections that have been idle for a specific duration.server_lifetime: Forces the closing of a connection after a maximum age to prevent memory leaks or stale state.The fundamental lack of client-side idle timeout configuration is consistent across both PostgreSQL and MySQL drivers in Prisma. However, the server-side mechanisms differ. MySQL uses wait_timeout and interactive_timeout to close idle connections, whereas PostgreSQL relies on the session and transaction timeouts mentioned above.
To verify if connections are accumulating or being reclaimed, monitor the database activity directly. In PostgreSQL, use the following query to identify long-running idle sessions:
SELECT pid, state, query_start, state_change
FROM pg_stat_activity
WHERE state = 'idle' AND state_change < now() - interval '5 minutes';
Missing Diagnostic Detail: Are you using Prisma Accelerate or a standard Node.js deployment? If using Accelerate, connection pooling is managed by the Prisma Data Proxy, and server-side PostgreSQL settings may be bypassed or overridden by the proxy's own internal pooling logic.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.