Free tools Windows power users keep installed
One-click scans. No signup required.
Fix an ASP.NET Core database connection leak by ensuring each DbContext, connection, command, reader, and transaction has a bounded lifetime and is disposed promptly. But first identify what is actually exhausted: a live SQL Server session is not, by itself, proof of a leak, because a closed logical connection can leave its physical connection available in the provider’s pool.
First determine whether you have a leak or a pool timeout
EF Core typically opens the provider connection just before a database operation and closes it afterward. With connection pooling enabled, closing the logical connection can return the physical connection to the pool rather than shutting down the server session. A session that remains visible on the database therefore does not alone establish that application code is holding a connection open. See EF Core advanced performance topics and SQL Server connection pooling.
As an Amazon Associate I earn from qualifying purchases.
Separate three symptoms: server sessions that keep accumulating, a client-side connection-pool timeout, and a limit or pool problem specific to another database provider. They can overlap, but they are not interchangeable. A pool timeout can result from connections not being returned, but also from slow queries, blocked or long-running transactions, high concurrency, fragmented pools, or database capacity limits.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11For SqlClient, correlate counters with server activity
For Microsoft.Data.SqlClient, inspect available diagnostic counters for active and free pooled connections, pool groups, stasis, hard and soft connects or disconnects, and reclaimed connections. A reclaimed-connection signal can point to logical connections that were not disposed, but it is a clue rather than a complete diagnosis. Compare a time window of client counters with server sessions, waits, blocking, query duration, transaction duration, request concurrency, and database capacity. Counters alone do not prove the root cause; Microsoft describes relevant pool behavior and configuration in its SQL Server connection pooling guidance.
#1 Best Overall
Keep each DbContext within one unit of work
In a typical ASP.NET Core application, register the context with AddDbContext<TContext>. It uses scoped lifetime by default, which commonly means one context per request scope. Dependency injection disposes the context when that scope ends; do not retain it in a singleton or another object that outlives the work it serves.
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(connectionString));
For a context created manually, or one obtained from a factory, dispose it when the unit of work finishes. In asynchronous code, use await using where the context supports asynchronous disposal. Microsoft’s DbContext lifetime, configuration, and initialization guidance says: “It is important to dispose the DbContext after use.”
Rank #2
Await operations and avoid concurrent use of one context
Await each EF Core asynchronous operation before using that same context again. Do not run parallel operations against one context; use a separate context for each concurrent unit of work. A DbContext is not thread-safe, and some exceptions caused by invalid concurrent use can leave it unrecoverable.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsDispose manually managed connections and their related objects
If application code creates or explicitly opens a SqlConnection, make cleanup deterministic with a using scope, or await using where appropriate. Dispose commands, readers, and transactions as well, keeping each lifetime no longer than its work requires. Ensure exceptions and early returns still leave the scope. Merely letting a connection variable go out of scope is not a substitute for explicit cleanup: Microsoft’s SqlConnection class documentation states, “If the SqlConnection goes out of scope, it won’t be closed.”
await using var connection = new SqlConnection(connectionString);
await connection.OpenAsync();
// Execute commands and consume or dispose readers here.
With pooling enabled, closing or disposing a logical connection returns it to the pool. Disabling pooling is not a leak fix: disposal then closes the underlying server connection and can add connection-setup overhead.
Check pool fragmentation and configured limits
For SQL Server ADO.NET, pools are associated with exact connection-string matches. Even differences in keyword order can create separate pools, splitting available capacity across pool groups. Use consistent connection strings for workloads intended to share a pool, and inspect the deployed application’s actual strings and active pool groups.
Rank #4
Microsoft’s SQL Server provider documentation lists a default maximum pool size of 100 and a default 15-second wait for a connection request before timeout. These are provider defaults, not universal EF Core settings; verify the provider, version, and deployed configuration before relying on them. Do not raise Max Pool Size until you have checked disposal and established that the database can support the aggregate connection demand across all application instances.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Understand the separate jobs of the two pools
EF Core context pooling and ADO.NET connection pooling address different objects. AddDbContextPool reuses DbContext instances; the provider separately pools physical database connections. Context pooling does not repair connections that application code fails to return.
EF Core resets its own context state when a pooled context is reused, but it does not generally reset state that application code changed directly in the driver. If code manually opens a connection or changes driver state while using a pooled context, restore that state—for example, close the connection—before the context is returned to its pool. Otherwise, that state can affect later use.
Use the evidence to choose what to fix
| Possible cause | Evidence to inspect |
|---|---|
| Connection or reader not disposed | Code paths, exception paths, and SqlClient reclaimed-connection diagnostics. |
| Slow query or long transaction | Query and transaction duration, server waits, and blocking. |
| High concurrency or insufficient capacity | Active and free pooled counts, request concurrency, database limits, and total demand across instances. |
| Pool fragmentation | Exact connection strings and active pool groups. |
| Normal pooling mistaken for a leak | Logical close or dispose behavior compared with physical server-session lifetime. |
| Concurrent DbContext use | Unawaited asynchronous work or parallel operations sharing one context. |
Use these signals to prioritize investigation, then trace the application’s connection and transaction scopes over the same time window. The specific counters and pool defaults above apply to Microsoft.Data.SqlClient and SQL Server. Other providers, including PostgreSQL, MySQL, and SQLite, have their own pooling behavior, limits, and diagnostics; consult the documentation for the provider actually deployed.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




