Recommended strategy for max‑size
First answer the question: size each Quarkus instance’s quarkus.datasource.jdbc.max‑size so that the sum of all instances stays safely below the database’s global connection limit.
- Determine the database’s maximum allowed connections (e.g.,
max_connections in PostgreSQL).
- Divide that limit by the number of Quarkus nodes in the cluster to get a per‑node ceiling.
- Apply a safety margin (typically 10‑20 %) to absorb traffic spikes and unexpected bursts:
per‑node max‑size = floor((DB limit × safety factor) / node count)
- Set
quarkus.datasource.jdbc.max‑size to that value.
Setting min‑size for baseline load
To avoid connection‑creation latency during normal traffic, configure min‑size to cover the expected average concurrent request count that needs a DB connection.
- Estimate average concurrent requests (e.g., from historic metrics or load‑test averages).
- Set
quarkus.datasource.jdbc.min‑size to that number, but never exceed the per‑node max‑size.
Tuning acquisition‑timeout to spot leaks vs. spikes
The acquisition timeout should be long enough to tolerate the longest legitimate connection‑hold time, yet short enough to surface a genuine leak or chronic undersizing.
- Measure the typical maximum time a request holds a connection (e.g., longest query + transaction commit). Call this
T_hold_max.
- Set
quarkus.datasource.jdbc.acquisition-timeout to a value slightly above T_hold_max (e.g., T_hold_max + 30 s). This allows temporary spikes to wait without timing out.
- If you observe frequent acquisition‑timeout warnings, check two things:
- Are wait times approaching the timeout? If yes, the pool may be undersized – increase max‑size.
- Are a small number of threads holding connections far longer than
T_hold_max? That pattern suggests a leak – inspect application code for unclosed connections or missed finally blocks.
Verification steps (scoped, safe)
Enable Agroal statistics (via JMX, MicroProfile Metrics, or the Quarkus dev UI) and run a load test that mimics peak traffic.
- Watch
connectionCheckoutTime and connectionWaitTime. If average wait time nears the acquisition‑timeout, consider raising max‑size.
- Monitor
connectionCreationRate. A low rate during baseline indicates min‑size is sufficient; a high rate suggests min‑size is too low.
- Check the database’s actual connection count (e.g.,
SELECT count(*) FROM pg_stat_activity; for PostgreSQL) to ensure the summed pool usage stays below the global limit.
Missing diagnostic detail
To finalize the max‑size calculation, you need the observed peak concurrent request count that requires a DB connection. If this number differs significantly from your estimate, the per‑node max‑size should be adjusted accordingly.