When working with ASP.NET MVC and SQL Server, you might run into the dreaded error:

“The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.”

This error is more frequent than it ought to be; however, it is also very fixable. In this article, we will look at the causes of this, the operation of connection pooling, and what you can do to prevent and fix it in your ASP.NET MVC apps.

Connection Pooling:

Connection pooling is a performance feature provided by ADO.NET. Instead of creating a new connection to the database every time one is needed (which is expensive), a pool of reusable connections is maintained.

So, when you call:

    SqlConnection conn = new SqlConnection(connectionString);
    conn.Open();


You're actually borrowing a connection from the pool. When you call conn.Close() or conn.Dispose(), you're returning it back to the pool.

But here’s the catch: If you forget to close a connection — it stays out of the pool. Eventually, the pool runs dry. And when that happens, new requests wait until the timeout period, then throw the error.


 Let's try to understand root cause of the error

Let’s break down the error message:

“All pooled connections were in use and max pool size was reached.”

This means:

  • Your app is using a shared pool of connections (default max size = 100).

  • All connections are currently checked out and not returned.

  • Your app is trying to open a new connection.

  • It waits (default is 15 seconds).

  • It fails after timeout if no connections are returned.

Example:

    public ActionResult GetUsers()
    {
        SqlConnection conn = new SqlConnection(connectionString);
        conn.Open();

        SqlCommand cmd = new SqlCommand("SELECT * FROM Users", conn);
        SqlDataReader reader = cmd.ExecuteReader();

        // do something with reader...

        // forgot: conn.Close();
        return View();
    }


This code opens a connection but never closes it. Over time, as more users hit this endpoint, connections are never returned — and eventually the pool hits its max size.

Always Dispose Your Connections

The best practice is to use a using block, which ensures the connection is closed and returned to the pool, even if an exception is thrown.

    public ActionResult GetUsers()
    {
        using (SqlConnection conn = new SqlConnection(connectionString))
        {
            conn.Open();
            using (SqlCommand cmd = new SqlCommand("SELECT * FROM Users", conn))
            {
                SqlDataReader reader = cmd.ExecuteReader();
                // work with reader
            }
        }

        return View();
    }


You can also fix this by increasing the connection pool size in your db connection string

Default Connection Pool Settings in ADO.NET

SettingDefault Value
Max Pool Size100
Min Pool Size0
Connection Timeout15 seconds

Example

If you use a connection string like this:

    string connStr = "Server=.;Database=MyDB;Trusted_Connection=True;";


It implicitly uses:

Max Pool Size=100; Min Pool Size=0; Connection Timeout=15;


So, at most 100 active connections can be in use at the same time. If all 100 are in use and more requests come in, they’ll wait until a connection is returned to the pool — and if not returned within 15 seconds, they’ll throw:

"The timeout period elapsed prior to obtaining a connection from the pool."


🙏 Thank you for reading!

Thank you for taking the time to read this blog!

If you have any questions or need help with something, feel free to drop a message in the comments or contact section. I’ll get back to you as soon as possible.

Happy Learning! 😊

Leave a Reply

Your email address will not be published. Required fields are marked *


Talk to us?

Post your blog

F.A.Q

Frequently Asked Questions