TutorialJul 20, 2026 · 8 min read

MCP database connection pool sizing: capacity, queues, and backpressure

An MCP database server can be read-only, well scoped, and still take production down.

The failure usually starts quietly. Several agents call tools at once. Each tool opens or borrows a database connection. Queries run longer than the request path was designed for. The pool fills, callers queue, retries arrive, and a small burst becomes sustained pressure.

Connection-pool sizing is therefore not a single configuration value. It is a capacity contract between agent concurrency, query behavior, and the database.

Start with the database budget

Do not begin with the maximum number of agent sessions. Begin with the connections the database can safely dedicate to this workload after reserving capacity for the application, administration, migrations, monitoring, replicas, and incident response.

A database that permits 200 connections does not give the MCP service a budget of 200. Memory, CPU, lock contention, cache churn, and other clients usually make the useful limit much lower.

Record the budget explicitly and assign it across MCP server replicas. Ten replicas with pools of 20 create a possible 200 database sessions even if each individual configuration looks conservative.

Estimate demand from tool calls, not chat sessions

One conversation may issue several calls in parallel. A single tool may perform multiple queries. Retries may overlap the original attempt when cancellation is incomplete.

Measure at least four values:

  • peak concurrent tool executions;
  • database connections held per tool execution;
  • p50, p95, and p99 connection hold time;
  • the fraction of calls that wait, time out, retry, or cancel.

A rough starting estimate is concurrent database work multiplied by connections per execution. The production limit must then be capped by the database budget, not by demand. Excess work belongs in a bounded queue.

Use Little's Law as a sanity check

For a stable flow, average concurrency is approximately arrival rate multiplied by average time in the system. If 20 database-backed tool calls arrive each second and hold a connection for 250 milliseconds, the average active demand is about five connections.

That is not the final pool size. Tail latency, bursts, uneven tools, transactions, and replicas matter. But it exposes impossible assumptions. If the measured arrival rate and hold time imply 40 active connections, a pool of five can only work by creating a queue.

Make the queue visible and bounded

A full pool should not create an invisible wait with unlimited duration. Define:

  • a maximum queue depth;
  • a pool-acquisition timeout;
  • a statement timeout shorter than the end-to-end tool deadline;
  • cancellation that reaches the database;
  • a structured overloaded response that callers do not retry immediately.

Return retry guidance only for failures that are actually transient. Add jitter and a total attempt budget. Otherwise every waiting agent becomes another request generator.

Related: Rate limits for MCP database servers.

Separate fast tools from expensive tools

A metadata lookup and a quarter-wide aggregation should not compete under identical limits. Classify tools by expected cost and use separate concurrency limits or pools when one class can starve another.

The expensive path may need a smaller concurrency limit, stricter date ranges, approved summaries, or an asynchronous job interface. The fast path should remain available for health checks and bounded operational questions.

Related: AI database query budgets.

Account for PgBouncer semantics

A pooler can reduce server-side connection pressure, but it does not remove the need for admission control. Transaction pooling also changes which session features are safe. Session state, temporary tables, prepared statements, and per-session settings need explicit validation for the selected mode.

Test with the exact application driver, pooler mode, TLS path, database role, and query mix used in production. A benchmark that bypasses the pooler or uses one simple query measures a different system.

Load-test failure, not only throughput

A useful test ramps concurrent tool calls while recording:

  • active, idle, and waiting connections;
  • pool acquisition and query latency;
  • queue depth and rejection count;
  • database CPU, memory, locks, and replication lag;
  • timeouts, cancellations, retries, and abandoned work;
  • latency of the non-MCP application workload.

Then interrupt the database, exhaust the pool, slow one query class, and restart a server replica. Verify that queues drain, cancelled work releases connections, and retries remain bounded.

A practical rollout sequence

  1. Reserve a database connection budget for MCP workloads.
  2. Divide it across maximum server replicas.
  3. Measure connection hold time by tool and workload class.
  4. Set bounded queues, acquisition timeouts, statement timeouts, and cancellation.
  5. Add per-tool or per-class concurrency limits.
  6. Load-test bursts and failure cases with the real pooler path.
  7. Alert on queue growth and pool saturation before database saturation.

Where Conexor fits

Conexor provides MCP infrastructure for connecting AI clients to databases and APIs. Pool limits, query boundaries, and observable failures are part of making that access operationally predictable rather than merely connected.

Plan an MCP server setup

For the broader production review, see the MCP server for Postgres production checklist.

Relay

Quick questions

Relay

Quick questions

Ask me