Skip to main content

How Long Does MySql.Data Keep Idle Connections in the Pool?

· 5 min read
Jagdish Kumawat
Founder @ Dewiride

After a burst, a connection pool holds a lot of open connections. How long do they stay? I opened 8, closed them, and counted them every minute: they go after about 3 minutes, down to Minimum Pool Size.

The Test​

This opens 8 connections at once, closes them, then counts them on the server each minute. The counting uses a connection string with no database, which makes a separate pool, so it doesn't disturb what it's counting:

min-pool.cs
#:package MySql.Data@26.10.0

using MySql.Data.MySqlClient;

var connectionString = Environment.GetEnvironmentVariable("MYSQL_CONNECTION_STRING")
?? throw new InvalidOperationException("Set the MYSQL_CONNECTION_STRING environment variable first.");

// Opens 8 connections at once, closes them, then prints how many stay open as time passes.
var open = new List<MySqlConnection>();
for (var i = 0; i < 8; i++)
{
var connection = new MySqlConnection(connectionString);
await connection.OpenAsync();
open.Add(connection);
}

async Task PrintCountAsync(string label)
{
await using var check = new MySqlConnection(connectionString.Replace("Database=inventory;", ""));
await check.OpenAsync();
await using var command = new MySqlCommand(
"SELECT COUNT(*) FROM performance_schema.threads WHERE PROCESSLIST_USER = 'pool_demo' AND PROCESSLIST_DB = 'inventory'",
check);
Console.WriteLine($"{label}: {await command.ExecuteScalarAsync()} connections");
}

await PrintCountAsync("All 8 open");

foreach (var connection in open)
{
await connection.DisposeAsync();
}

await PrintCountAsync("All 8 closed");

for (var minute = 1; minute <= 5; minute++)
{
await Task.Delay(TimeSpan.FromMinutes(1));
await PrintCountAsync($"After {minute} min");
}

The account here is pool_demo, with SELECT on inventory and on performance_schema.threads.

With the Default​

Output, with no Minimum Pool Size
All 8 open: 8 connections
All 8 closed: 8 connections
After 1 min: 8 connections
After 2 min: 8 connections
After 3 min: 8 connections
After 4 min: 0 connections
After 5 min: 0 connections

Closing all 8 didn't close any: they went back to the pool. Between 3 and 4 minutes, they were gone. An earlier test of a running API, polling every 15 seconds, had 20 connections until 183 seconds, and none at 198.

With Minimum Pool Size=3​

Connection string
…;SslMode=Required;Minimum Pool Size=3
Output
All 8 open: 8 connections
All 8 closed: 8 connections
After 1 min: 8 connections
After 2 min: 8 connections
After 3 min: 8 connections
After 4 min: 3 connections
After 5 min: 3 connections

Eight connections staying for 3 minutes after being closed, then falling to 0 with the default and to 3 with Minimum Pool Size=3.

It kept 3, as asked. Those stay open however long they're idle.

Why About 3 Minutes​

Oracle's documentation explains it: "Connector/NET runs a background job every three minutes and removes connections from pool that have been idle (unused) for more than three minutes." The driver's source has the same number, 180 seconds, and no connection string option changes it. So the exact moment depends on when the job next runs, which is why it's "about".

Minimum Pool Size: Should You Set It?​

It keeps connections ready, so the first request after a quiet spell doesn't pay for opening one. The price is connections held open for ever. Things to know:

  • It doesn't open them at startup. With Minimum Pool Size=5, the API held no connections until its first request, and that request opened all 5, taking 0.65 seconds in all.
  • Above Maximum Pool Size, it's quietly lowered to match.
  • For most apps, leave it at 0. A connection takes a fraction of a second to open. Set it if that delay matters after quiet periods.

Does It Conflict with wait_timeout?​

MySQL closes a connection after wait_timeout, 8 hours by default. The pool closes its idle ones long before that. With a minimum set, connections could reach it, and the driver copes: I set wait_timeout to 5 seconds, and the next request got a new connection, with no error.

Common Mistakes​

MistakeWhat happensDo this instead
Reading Sleep connections as a leakThat's the pool, for up to 3 minutesCheck again later
A high minimum, to feel safeConnections sit idle for ever, and count against max_connectionsLeave it at 0
Expecting closing to close the connectionIt goes back to the poolClear the pool if you need that

Troubleshooting​

SymptomLikely causeFix
Connections stay for hoursMinimum Pool Size, or they're being usedCheck the setting and PROCESSLIST_TIME
The first request after a quiet spell is slowThe pool emptiedSet a small minimum, if it matters
ERROR 1142 from the counting queryThe account can't read performance_schema.threadsGrant SELECT on it, or use an administrator

Conclusion​

MySql.Data closes idle connections after about 3 minutes, down to Minimum Pool Size, and you can't change the timing. For most apps, the default of 0 is right.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.