TimeoutException caused by connection pool exhaustion in EF Core
0 reputation · 10 Aug 2021, 19:34 UTC
0 reputation · 10 Aug 2021, 19:34 UTC
In a high‑concurrency ASP.NET Core application using EF Core 8, a TimeoutException occasionally bubbles up from DbConnection.Open. The exception stack shows the ADO.NET provider throwing due to the underlying connection pool being exhausted. The application uses DbContextPool with default settings, and the connection string contains Pooling=true;Max Pool Size=100. The errors appear intermittently, not consistently on every request.
The exact cause of the pool exhaustion is unclear. Possibilities include:
DbContext instances leading to leaked connections.There is no current telemetry on pool usage or connection churn, and the application’s transaction scopes vary between short and long operations.
DbContextPool configuration or connection string settings can mitigate intermittent pool exhaustion?A TimeoutException occurring during DbConnection.Open is an ADO.NET provider error, not an EF Core internal failure. It indicates that the application requested a connection, but all 100 connections in the pool were in use, and the request timed out while waiting for one to be released.
To distinguish pool exhaustion from transient network faults, examine the exception message and inner exceptions:
SocketException, a DNS resolution failure, or a provider-specific error code indicating a lost connection or a server-side reset.To confirm the pool is hitting its limit, monitor the following:
dotnet-counters to monitor active connection counts. If the active count plateaus at 100 (your Max Pool Size) during the spikes, exhaustion is confirmed.Information level logging for Microsoft.EntityFrameworkCore.Database.Connections. Correlate ConnectionOpened and ConnectionClosed events with the timestamps of the TimeoutException.sys.dm_exec_connections in SQL Server) to see the number of active sessions originating from the application's IP.Since DbContextPool reuses the DbContext object but does not keep the underlying database connection open between requests, increasing the context pool size will not fix ADO.NET pool exhaustion. Instead, apply these adjustments:
Max Pool Size=200 (or higher) in the connection string to accommodate transient concurrency spikes.DbContext scope. Connections are held until the transaction completes or the context is disposed.DbContext instances are registered as Scoped in ASP.NET Core DI. If you are manually creating contexts via a factory, verify they are wrapped in using blocks.To refine this recommendation: Are you using TransactionScope or explicit IDbContextTransaction blocks that wrap asynchronous calls to external services? If so, the connections are being held open far longer than the database work requires, which is the most common cause of pool exhaustion in EF Core.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.