What happens when Max Pool Size is reached?
When the application requests a new connection and all pooled connections for that exact connection string are in use, the pool manager does not create a new physical connection beyond the limit. Instead, the request is placed in an internal wait queue. It remains blocked until either a connection is returned to the pool (by calling Dispose/Close) or the connection‑timeout interval elapses. If a connection becomes available first, the request proceeds normally; if the timeout expires first, ADO.NET throws a SqlException with a timeout message.
Confirmed facts
- The default Max Pool Size for SqlConnection is 100 connections per unique connection string.
- You can raise or lower this limit by adding
Max Pool Size=N to the connection string (N ≤ 32767).
- Each distinct connection string (including user, password, Initial Catalog, or any other attribute) gets its own pool, so the limit applies per string.
- Exceeding the limit causes the wait‑or‑timeout behavior described above; no new physical connection is created until the limit is freed.
Likely explanation
The pool manager uses an internal blocking queue. When the limit is hit, new Open() calls wait on a semaphore‑like construct. The wait respects the Connection Timeout value; if the timeout expires before a connection is released, the wait is aborted and an exception is raised. This explains why you may see increased latency rather than an immediate failure when the pool is near its limit.
Steps to diagnose and mitigate
- Verify the exact connection string used throughout the code (including any dynamic parts).
- Monitor pooled connections:
- Performance counter:
.NET Data Provider for SqlServer\NumberOfPooledConnections
- Or query SQL Server:
SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE program_id = ... (adjust filter to identify your app).
- If the counter regularly hits the configured Max Pool Size, consider:
- Increasing
Max Pool Size in the connection string (after confirming the database server can handle more concurrent sessions).
- Ensuring every
SqlConnection is wrapped in a using block or explicitly Dispose/Close to return it promptly.
- Reviewing long‑running operations that hold connections open (e.g., large data reads without
Async or streaming).
- If you notice many different connection strings in use, audit the code for dynamic string building (e.g., appending user‑specific values) and consolidate to a single pool where possible.
Missing detail that would change recommendation
Are you observing timeout exceptions (SqlException with timeout message) when the pool is exhausted, or are you only seeing increased latency without exceptions? Knowing whether the timeout is being hit will determine if you need to raise the limit, reduce usage, or adjust the connection‑timeout value.