skip to content

A JMeter plan drives a reporting query straight at the database. How would you choose Max Number of Connections?

level: principalimportance: should knowfreq 41%

answer

  1. Ask what the pool represents
  2. One field or the other carries concurrency
  3. A default timeout should not decide failures
  4. Record the settings with the numbers

basics

~20 s

Decide first what the pool is meant to represent. Leave it at 0 and the thread count alone sets the connections the database sees; pin a positive number and JMeter's own pool becomes the constraint, with waits and, past Max Wait, failed samples.

solid answer

~60 s

There is no universally correct number, so make the choice explicit. `Max Number of Connections` = `0` gives every thread its own single connection: the plan opens as many connections as it runs threads, nothing queues inside JMeter, and the database sees exactly the concurrency the thread group applies. A positive **N** builds one shared DBCP pool of N: threads beyond N block inside the pool for up to **Max Wait (ms)** (default `10000`) and then produce failed samples whose response code is `null 0` — no SQLState, because the failure comes from the pool and not from the database. Pick `0` when you want the database's own behaviour under a stated number of connections. Pick a positive N only when you deliberately want to reproduce a specific pool size — and then say so in the report, because the number you publish is then partly a property of your plan. Either way, record the setting alongside the results: without it, a run's numbers cannot be compared with the next one.

go deeper

for a junior

Recall that this field is a real choice with consequences, and that 0 means one connection per thread rather than an unlimited pool.

for a middle

Explain what each setting makes the plan do, including that Max Wait (ms) turns a shared pool's exhaustion into failed samples after ten seconds by default.

for a senior

Show how you read connect time to separate a queue inside JMeter from time spent at the database, and how you keep the opening window of a run from flattering or spoiling the result.

for a principal

Own the convention and the write-up: which setting the team's plans use by default, what a report must state for two runs to be comparable, and what a direct-to-database run is allowed to be quoted as.

This field is the one real design decision in a direct-to-database JMeter plan, and it is a decision rather than a default because the two settings measure different things. ## Frame the choice as "what does the pool represent?" - **`0` — the pool represents nothing.** Every thread gets a private pool of one connection, built the first time that thread runs a JDBC Request. Nothing inside JMeter throttles: the number of connections the database sees is the number of threads the plan is running, and the queue, if there is one, forms at the database. - **A positive N — the pool represents something you chose.** One shared DBCP pool of N is built at test start. Threads beyond N wait inside the pool, and `Max Wait (ms)` decides how long before the sample fails. The results now describe the database *behind a pool of N*, which is a different subject. Neither is more honest than the other. What is dishonest is publishing a number without saying which one you used. ## What the sample's timing actually covers The sampler starts timing before it asks for a connection, so any wait for the pool is inside the sample's elapsed time; the moment the connection arrives is marked as the sample's connect time. That gives you a concrete way to see the pool in the results: a rising connect time on a shared pool is the plan's own queue, not the database's. It also bounds what the run is about. The driver and the DBCP pool live in the JMeter JVM. Acquiring the connection, executing the statement and reading the rows all happen between the injector and the database, with no application in the path. The run therefore characterises the database and that driver as this plan exercises them — a real and useful thing to know, and not the same thing as a measurement taken through a service. ## A workable decision procedure 1. **Write down the question the run must answer**, in the form "how does this query behave at C concurrent connections?" If you cannot state C, you are not ready to size anything. 2. **Default to `0`** and set the thread group's thread count to C. One field now carries the concurrency, and it is the field everyone reads first. 3. **Choose a positive N only for a reason you can name** — most often "the service in front of this database runs a pool of N and I want the same ceiling". Then set `Max Wait (ms)` deliberately rather than leaving the 10-second default to decide when samples start failing. 4. **Check the first samples.** `Preinit Pool` is off by default, so connection establishment is paid by the earliest requests. On a shared pool you can tick it and DBCP opens the whole pool at test start; at `0` the tick buys nothing, because each thread's pool is built inside that thread's first JDBC Request, after the sampler has started timing — there, discard the opening window. Either way, do not explain the shape away. 5. **Decide about validation.** `Test While Idle` is on by default and uses `Validation Query`; leaving that field blank falls back to the driver's own `isValid()` check, which suits most databases. If you supply a query, remember the pool also validates once at creation. 6. **Record the settings with the results.** `Max Number of Connections`, `Max Wait (ms)`, thread count, `Limit ResultSet` and `Query timeout (s)` are the five fields that make two runs comparable. ## Failure modes to plan against | Setting | The way it bites | |---|---| | `0` with a large thread group | as many database connections as threads; the database may refuse them long before JMeter notices | | N smaller than the thread count | threads queue in JMeter, connect times climb, and past `Max Wait (ms)` samples fail with a pool error carrying no SQLState | | N equal to the thread count | the manual's own advice for shared pooling, which is effectively `0` with extra bookkeeping | | `Max Wait (ms)` left at its default | the moment the run starts producing failures is decided by a default nobody chose | ## What to hand back A defensible write-up from a plan like this names the query, the setting of `Max Number of Connections`, the thread count, whether rows were bounded with `Limit ResultSet`, and the fact that no application sat in the path. Those five facts let the next person reproduce the run or argue with it. A single response-time figure without them cannot be reproduced, and should not be quoted.

  • How can you tell from the results that JMeter's own pool, not the database, was the queue?
    Watch the sample's connect time. The sampler begins timing before it asks the pool for a connection and marks the connection-acquisition point as soon as one arrives, so time spent waiting for a shared pool shows up there while the statement's own execution does not. A connect time that climbs with thread count on a fixed pool is the plan queueing on itself.
  • Which settings must a report from such a plan state for the numbers to be reproducible?
    At minimum `Max Number of Connections`, `Max Wait (ms)`, the thread count, `Limit ResultSet` and `Query timeout (s)`, plus the query itself. Those decide how many connections the database saw, when samples begin failing, how many rows crossed the wire and whether a slow query could run forever.
  • Is there ever a reason to prefer a shared pool in a load plan?
    Yes, when the pool size is the thing under test - reproducing a service's configured pool ceiling, or checking what happens to callers when it is exhausted. Outside that, the manual recommends 0, and its advice for shared pooling is to set the size equal to the thread count so threads do not wait, which removes most of the benefit.

saying these in an interview costs you the question

  • Picks a pool size with no stated concurrency target
  • Leaves Max Wait at its default and calls failures database errors
  • Reports a response time without the pool setting
  • Treats per-thread connections as free at any thread count
  • Presents a database-only run as a service measurement