Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Connection Pool Sizing

ASecurity

Sizing and diagnosing a JDBC connection pool: L = λ × W where W is connection hold time rather than query latency, the database-side ceiling, HikariCP timeouts and lifetimes, transaction boundaries and idle-in-transaction, N+1 detection, JDBC batching, and what virtual threads change. Use when choosing maximumPoolSize, when connection-timeout is 0 or 30 s, when threads wait for connections under load, when HTTP or queue calls happen inside @Transactional, when connections die silently behind ...

2 stars
0 votes
0 copies
0 views
Added 9/19/2026
developmentjavasqlexpressspringapidatabasebackendperformance

Works with

cliapi

Security Analysis

A100/100

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add robsonkades/agent-skills --skill connection-pool-sizing --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Connection Pool Sizing?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Connection Pool Sizing
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/robsonkades-connection-pool-sizing/badge)](https://www.skillsdirectory.com/skills/robsonkades-connection-pool-sizing)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: connection-pool-sizing
description: >
  Sizing and diagnosing a JDBC connection pool: L = λ × W where W is connection hold time
  rather than query latency, the database-side ceiling, HikariCP timeouts and lifetimes,
  transaction boundaries and idle-in-transaction, N+1 detection, JDBC batching, and what
  virtual threads change. Use when choosing maximumPoolSize, when connection-timeout is 0 or
  30 s, when threads wait for connections under load, when HTTP or queue calls happen inside
  @Transactional, when connections die silently behind a firewall or load balancer, when
  hibernate.jdbc.batch_size appears not to work, or when raising the pool is proposed as the
  fix. Does not cover the general queueing arithmetic (littles-law-and-queueing), thread
  pool sizing (thread-sizing-and-virtual-threads), or caching to reduce load
  (caching-strategies).
---

# Connection Pool Sizing

## Purpose

Size a database pool from measurement and distinguish insufficient local capacity from database
saturation, leaks and long-held connections. Raising `maximumPoolSize` helps only if measured
database headroom can absorb the extra concurrent work within the required SLO.

## Workflow

Before applying settings, inspect compiler/runtime, resolved HikariCP, Spring Boot, Hibernate and
JDBC driver versions, database engine/version, metrics binding and transaction/connection release
mode. No single Java baseline is declared for this diagnostic workflow; the SQL examples target
PostgreSQL, and virtual-thread APIs require Java 21+. Preserve target versions. Missing workload or
capacity evidence requires a measurement plan and conditional recommendation, not an invented size.

1. **Measure `W`**, the mean connection **hold** time, with `hikaricp.connections.usage`;
   inspect p50/p99 separately for tails. Hold time runs from successful checkout until return to
   the pool, which can include time before the first statement and after commit. Verify the metric
   adapter; completed-use samples can omit connections still stuck or leaked.
2. **Compute mean concurrency `L = λ_borrow × mean(W)`** using completed borrows/second and
   hold durations from the same pool and stable interval, not query rate or a percentile. Then model a candidate pool against the
   arrival distribution and latency/error budget. A fixed 1.5× margin is a starting hypothesis,
   not a sizing law.
3. **Establish the database-side budget** with the database owner: reserved administrative
   connections, total application instances, workload classes, CPU saturation, storage latency,
   lock pressure, and failover topology. The familiar `cores × 2 + spindles` expression is a
   benchmark heuristic, not a portable ceiling. If demand exceeds the measured safe budget, reduce
   hold time or arrival rate before adding concurrency.
4. **Set the timeouts and lifetimes** deliberately (see Rules).
5. **On an incident, check in order**: `pending` and `acquire` p99 (is it the pool?),
   `usage` p50 versus p99 (does a minority hold connections far too long?),
   `pg_stat_activity` for long `idle in transaction` sessions (what code is holding a transaction
   open while no statement runs?), then `pg_stat_statements` ordered by `total_exec_time` **and** by `calls`
   — high call counts identify candidates for per-request N+1 investigation.

## Rules

- At a fixed pool size, halving mean hold time doubles the ideal borrow-service capacity only
  if the workload and other bottlenecks remain unchanged. Confirm useful throughput and database
  health rather than treating that arithmetic as a measured end-to-end speedup.
- Pool waiting grows non-linearly near saturation, but a real database pool is not automatically
  M/M/c: arrivals may be bursty, hold times heavy-tailed, transactions correlated, and the database
  itself slows as concurrency rises. Use Erlang-C only as an explicit approximation and validate
  candidate sizes with production distributions or a representative load test.
- Never equate the pool to the container's thread count. Threads waiting for a connection can be
  intentional backpressure, but their wait must still fit the request deadline. For direct database
  connections, aggregate all pools across peak coexisting instances within the available session
  budget. This configured ceiling is separate from measured safe database execution concurrency.
  With a connection proxy, budget client connections and backend sessions separately; do not assume
  a one-to-one mapping or a vendor default (see the sizing reference).
- Avoid `connection-timeout=0`, which HikariCP treats as effectively unbounded. Its default is
  **30,000 ms** and its accepted minimum is 250 ms. Choose a finite value inside the caller's
  remaining deadline and validate the resulting rejection behaviour. Failing fast
  is what enables a circuit breaker, backoff retry and a degraded response — a long wait
  converts partial saturation into total unavailability.
  This timeout is pool-wide and covers acquisition, not query execution or the whole request.
  For shorter remaining budgets than the supported minimum, use deadline-aware upstream admission
  and a client cancellation policy; do not assume setting a sub-minimum value works.
- Set `max-lifetime` a few seconds **below** an enforced database or infrastructure connection
  lifetime when one exists; do not derive it from unrelated idle or request timeouts. Firewalls,
  load balancers and NAT gateways may drop idle TCP connections; pool keepalive, driver/OS TCP
  keepalive, validation, and JDBC socket timeouts cover different parts of that failure. HikariCP's
  `maxLifetime` default is 1,800,000 ms (30 min), and `0` means infinite. Current HikariCP defaults `keepaliveTime` to
  120,000 ms; older releases and some integrations used `0`. Verify the resolved version and
  effective configuration. Driver/OS TCP keepalive and JDBC socket timeouts address different
  failure modes.
  In-use connections are retired after return, so `maxLifetime` is not protection against an
  infrastructure cutoff during a long borrow. Account for hold duration and recovery margin.
- In Spring's default proxy mode, self-invocation such as `this.method()` bypasses transactional
  interception. Method visibility support depends on proxy type and Spring version; a separate
  proxied collaborator or `TransactionTemplate` makes the boundary explicit. AspectJ weaving has
  different semantics, so inspect the configured advice mode before diagnosing from source alone.
  Also inspect nested acquisition: `REQUIRES_NEW` can hold the outer transaction's connection while
  borrowing another for the inner transaction. Pool starvation can therefore occur with database
  headroom; review propagation semantics and peak simultaneous borrows before changing capacity.
- `idle in transaction` says that a transaction is open while the backend is not executing a
  statement. Correlate application traces and transaction age before attributing the gap to HTTP,
  messaging, user think time, or business logic. A 300 ms HTTP call inside
  `@Transactional`, while a connection is held, contributes at least 300 ms to that borrow.
  Only if every borrow has that delay is `pool_size / 0.3` an ideal upper bound. Old transactions
  may retain locks or cleanup horizons; inspect isolation, transaction age and `backend_xmin`
  rather than assuming every READ COMMITTED transaction holds one snapshot throughout.
- N+1 can consist of individually fast or slow statements and costs both round trips and database
  work. High `pg_stat_statements.calls` is a lead, not proof: correlate statement-count deltas
  with one endpoint invocation and result cardinality. Choose fetching/batching/projection from
  access and pagination needs, then test the count envelope across multiple cardinalities.
- `flush()` sends pending changes; `clear()` controls persistence-context retention. JDBC batch
  configuration is separate. Hibernate 6.6 disables insert batching with identity generation;
  changing ID strategy requires schema/compatibility evidence. Delegate fetch and batch design to
  `orm-fetch-and-batching-performance`; prepared-statement count alone does not prove batching.
- Hikari's contended borrow path can appear in `jdk.ThreadPark`; verify stack/blocker identity
  rather than treating every park as pool contention. Runtime JFC thresholds filter short waits;
  inspect them before concluding that absent events mean no queueing.
- Inspect effective isolation rather than assuming the engine default. For PostgreSQL 40001,
  retry the whole transaction in a fresh transaction, including reads and decisions, with bounded
  attempts/backoff/jitter only when external effects are safe. It also occurs at REPEATABLE READ;
  repeated failure or exhaustion remains an application-visible failure requiring diagnosis.
- Virtual threads do not change Little's arithmetic; they change where the bottleneck sits.
  Replacing a fixed worker pool can remove implicit admission control. The JDBC pool still bounds
  checked-out connections, but waiting tasks/memory need separate bounded admission and deadlines
  (`concurrency-limiting-and-bulkheads`).

## References

Return the measurement interval/population, mean and tail hold times, borrow rate, candidate pool
and aggregate database budget, competing diagnosis, and validation/rollback bounds. State which
checks ran and which claims remain conditional.

- [Sizing and configuration](references/sizing-and-configuration.md) — the calculation, the
  HikariCP settings with their real defaults, and the pre-deploy and monitoring checklists.
  Read when configuring or reviewing a pool.
- [Pool incident triage](references/incident-triage.md) — the ordered diagnostic path from
  pool metrics to `pg_stat_activity` to `pg_stat_statements` to `EXPLAIN`. Read during an
  incident where threads are waiting on the database.

Attribution

robsonkadesrobsonkades
View sourceMore from robsonkades →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

281612 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2132 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →