A saturated MySQL pool queues callers inside your own application
Fifty concurrent users need about five MySQL connections in a dev.to worked example, because the quantity to size against is simultaneous queries, and Go opens a connection only when a request asks for one.
The Engineer · Build desk

What happened
- It answers its own headline question flatly, saying that fifty concurrent users do not mean you need fifty MySQL connections, because concurrent users are not concurrent queries.
- MaxOpenConns is presented as a ceiling rather than a preallocation, with connections created as traffic needs them and zero possibly open while the application sits without database activity.
- In the worked example of fifty users online, perhaps five requests need MySQL at a given moment, and the accompanying diagram shows all five pool connections running queries.
- Once every connection in the pool is busy, the article says new requests that need a database connection may have to wait.
Why it matters
- constraint Since the cap is a hard ceiling and the queue forms on the borrow, an undersized pool is diagnosed from request latency in your own service rather than from anything the database reports.
- cost Whoever copies the snippet's idle settings decides how often the application re-pays connection setup, and that bill arrives as slower first requests after every quiet period.
- decision Choosing MaxOpenConns is a decision about total database exposure rather than a per-service detail, because each instance carries its own ceiling and they add up at the server.
- capability Separating users from queries makes pool sizing an instrumentable quantity, so the value can be argued from peak simultaneous queries instead of inherited from a tutorial.
With five connections busy, the sixth request that needs the database waits for one to be returned to the pool [6]. That wait happens on the borrow, inside your process, because the pool is an application-side collection of reusable connections that requests check out and hand back [9]. So the failure signature of an undersized pool shows up as your own handler latency; the database itself never reports an error. An app that has just started and reports zero open connections is behaving exactly as documented [5].
The walkthrough's own figures give a ratio worth naming. Fifty users online, perhaps five requests actually needing MySQL at a given instant, which is ten users per connection [13]. That is a claim about their workload. For it to transfer, your query durations have to be in the same range, roughly the same share of your requests must never touch the database at all, and your users have to spend as much time reading and typing as theirs do [3]. Change any one of those and the ratio moves. The number that survives the move is the count of queries in flight at peak, which is the thing MaxOpenConns is actually rationing.
The snippet sets two timers, two minutes of idle time and a thirty-minute lifetime, a fifteenfold spread [1][14]. The piece lists the difference between MaxIdleConns and ConnMaxIdleTime among the questions it set out to answer, and the text supplied here breaks off before it gets there [10]. That leaves the interesting gap undefended: MaxOpenConns is five while MaxIdleConns is one [1]. Connection setup is not free, since it can involve network communication, authentication, server-side resource allocation, session initialisation and extra CPU and memory [7]. A pool permitted to grow to five while retaining fewer idle sockets pays some of that setup again on the next burst. Whether it does, and how much, depends on what your driver does with MaxIdleConns, which is the line to read before you copy the four lines.
The multi-tenant trap comes down to arithmetic. The cap is stated per application: five open connections at the same time for that process [12]. Run the service in several instances and the server sees the cap once per instance, so the figure to compare against the database's own connection limit is MaxOpenConns multiplied by replica count [16]. Scaling out horizontally therefore raises database-side connection pressure without anyone editing the pool config. The distinction between users and queries is exactly what the article says matters for SaaS and multi-tenant systems [11], and the corollary is that tenant counts belong nowhere in this calculation.
What to watch
- The unread remainder of the dev.to piece: if it defines MaxIdleConns as a cap on retained idle sockets, the 5-open/1-idle pairing needs a rewrite before reuse.
- Driver and runtime release notes on pool semantics, since any change to idle handling moves what the two-minute and thirty-minute timers actually do.
- A measured trace of simultaneous in-flight queries at peak, which would replace the illustrative figure of five with a number from your own workload.
Clarity's read
What the record supports and how the coverage leans. The claims behind it follow.
Reality
- Evidence45
- Adoption
- Insufficient
- Hype gap+12
- Incentives20
- Confidence50
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
A dev.to walkthrough headlined "MySQL Connection Pooling Explained: Do 50 Concurrent Users Need 50 Database Connections?" opens with four Go configuration calls: SetMaxOpenConns(5), SetMaxIdleConns(1), SetConnMaxIdleTime(2 * time.Minute) and SetConnMaxLifetime(30 * time.Minute).
- [2]
The article's short answer to its headline question is that 50 concurrent users do not mean you need 50 MySQL connections.
- [3]
The article states that concurrent users are not the same as concurrent database queries, since users online may be reading a page, looking at previously loaded data, typing into a form, waiting before clicking, or calling an API that does not require the database.
- [4]
In the article's example of 50 users online, at a specific moment perhaps only 5 requests actually need MySQL, illustrated by a pool of five connections C1 to C5 all running queries.
- [5]
The article notes that MaxOpenConns = 5 does not mean Go immediately creates 5 connections at startup; connections are generally created as needed, and with no database activity 0 connections may exist.
- [6]
The article states that once all 5 connections are busy, new requests that need a database connection may have to wait.
- [7]
The article lists what creating a database connection can involve: network communication, authentication, server-side resource allocation, session initialization, and additional CPU and memory usage.
- [8]
The article calls creating and closing a connection per request inefficient once an application receives hundreds or thousands of requests.
- [9]
The article describes a connection pool as a collection of reusable database connections that a request borrows, uses for a query, and returns, after which another request can reuse the same connection.
- [10]
The article lists "What is the difference between MaxIdleConns and ConnMaxIdleTime?" among the questions it sets out to answer, and the supplied text breaks off mid-sentence before answering it.
- [11]
The article says understanding the distinction between concurrent users and connections is important when building scalable backend applications, especially for SaaS and multi-tenant systems.
- [12]
The article states that MaxOpenConns(5) means the application can have a maximum of 5 open database connections at the same time.
- [13]
In the article's example the ratio is ten concurrent users per busy database connection.
- [14]
The snippet's connection lifetime cap is fifteen times its idle-time cap.
- [15]
The five busy connections in the article's diagram put the pool exactly at its configured ceiling, the state in which a further borrower waits.
- [16]
Because the ceiling is stated per application, the connection count presented to the database server is MaxOpenConns multiplied by the number of running application instances.
Get this ledger inside ChatGPT. Ask about any of our stories and the answer brings its figure, each claim’s verdict and the sources. Free, no account.
Sources
1 independent publisher whose own reporting we read for this story.
- dev.toMySQL Connection Pooling Explained: Do 50 Concurrent Users Need 50 Database Connections?
1 article · August 29, 2026
Topics and entities
Follow any of these and your For You feed starts watching them — no settings page required.
Topics
- Go backend configurationFollow
- Backend capacity planningFollow
- Latency and contentionFollow
- Database connection poolingFollow