Connection pool exhausted: symptoms, cause, and the test that catches it

A new code path leaks or holds connections and the pool runs out under load.

Connection pool exhausted is documented by 5 accepted public reports from 4 organisations, 3 of them published in the last 5 years.

  • Likelihood: medium (3 public reports in 5 years)
  • Impact: medium (3 of 4 reports: availability)

5 public reports · verified 2026-10-21

Symptoms

User-visible

  • An average of 31 percent of code pushes over HTTPS and SSH failed, with a peak of 43 percent.[1]
  • Write operations on the website and the public API slowed down, and issues and pull requests showed degraded performance.[2]
  • Users who triggered urgent background jobs saw slowness for about 46 minutes.[3]
  • Users could not log in to the wallet apps, the web app or the dashboard.[4]
  • Every application system of the affected service was disrupted for 11 minutes.[5]

Monitoring-visible

  • Load on a primary database rose until its connection pool ran out.[1][2]
  • The background job queueing apdex breached its SLO and paged the on-call engineer.[3]
  • The connection pooler for urgent background jobs reached saturation, with lower job throughput and longer queueing times.[3]
  • Database connection data showed many connections that were opened and never closed.[4]
  • The database ran out of connections and fired system alerts before customer reports arrived.[5]

Root causes

  1. stage: code New code sent extra work to a primary database: an unexpectedly expensive query from a newly enabled code path in one report, and a newly deployed background job in the other. The added load exhausted the primary's connection pool.[1][2]
  2. stage: code A feature flag made the database load balancer check out a fresh connection for each health check. The health checks ran several times inside every background job, so each job held one extra connection and pool usage roughly doubled.[3]
  3. stage: code A condition in code shipped with a scheduled release opened a database connection and did not close it after the condition ended. The leak happened only under certain conditions.[4]
  4. stage: code A code change made indexing processes keep database connections open where their call paths crossed into older session management code. The stale connections built up under rising load.[5]

Public examples

  1. [1]GitHub, 2026-06-08. A recently enabled code path at GitHub issued an expensive query against a primary database, exhausting its connection pool so that an average of 31 percent of Git pushes failed for nine minutes. primary Elevated rate of Git push errors
  2. [2]GitHub, 2025-02-28. A newly deployed background job at GitHub increased load on the primary database hosts and exhausted the connection pool, raising write latency and request timeouts until the job was halted. primary Elevated Request Latency for Write operations on github.com and api.github.com
  3. [3]GitLab, 2024-11-05. GitLab rolled a feature flag out to 100 percent of pods that made the database load balancer check out an extra connection for health checks during every Sidekiq job, which saturated the urgent Sidekiq pgbouncer pool until the flag was disabled. primary Incident Review: The sidekiq_queueing SLI of the sidekiq service on shard low-urgency-cpu-bound has an apdex violating SLO
  4. [4]tada, 2023-01-11. After a scheduled release at tada, a code condition opened database connections without closing them, and when real traffic arrived new database connections timed out, taking down the Integration API and Wallet API until the code was fixed and redeployed. primary Connection issue to database
  5. [5]Close, 2020-11-25. A code change deployed at Close left database connections open where call paths crossed into older session management code, and stale connections accumulated until the application exhausted all connections to a backend database and all Close systems were disrupted for 11 minutes. primary Application loading issues

Test classes that catch it

Test classStageLimitationBasis
Integration testspre-deployAn integration test can assert that each job returns its connections, but at test data volume an expensive query against the primary database does not drain a pool sized for production.by design analysis
Load and performance testspre-deployA load test drains the pool only if its traffic takes the specific branch that leaves a connection open, and the reported leak occurred only under certain conditions.by design analysis
Canary and progressive delivery checkspost-deployA canary on part of the pods can show no pooler saturation, as at 1, 5, 20 and 50 percent of pods in report [3], because saturation appeared only once the flag reached 100 percent of pods.by design analysis

Risk

  • Likelihood: medium (3 public reports in 5 years)
  • Impact: medium (3 of 4 reports: availability)
Counts behind the grades
Accepted public reports4
Published in the last 5 years3
Impact stated: availability3
Impact stated: degraded1

How the grades are computed

Pre-release checklist

  • PR-01
  • PR-02
  • PR-03
  • PR-04
  • PR-05
  • PR-06
  • PR-07
  • PR-08
  • PR-09

First 30 minutes

  • FM-01
  • FM-02
  • FM-03
  • FM-04
  • FM-05
  • FM-06
  • FM-07
  • FM-08

Download the checklist

What catches this: catalogue entries

Listed because their own documentation or site names integration tests, load and performance tests, canary and progressive delivery checks on the verification date. Alphabetical. Not a recommendation.

Tools whose documentation names these test classes

Providers whose site names these test classes

Only on this page

Connection pool exhausted can stay hidden through a gradual rollout, because saturation appeared only once the flag reached 100 percent of pods [3]. In report [3], the connection pooler showed no saturation at 1, 5, 20 or 50 percent of pods. At that final step every background job held one extra connection, which roughly doubled client pool usage [3].

Report [4] shows the same gap after a release. Post-release tests in report [4] found no major issue. The leak surfaced when real traffic arrived around 7am, and the team first suspected networking before another team spotted connections that were opened and never closed [4].

Questions

What causes connection pool exhausted?

Reports [1] and [2] describe new code that sent extra load to a primary database: an expensive query and a new background job. Reports [4] and [5] describe code paths that opened database connections and never closed them. Report [3] describes a feature flag that added one held connection to every background job.

What are the symptoms of connection pool exhausted?

An average of 31 percent of code pushes failed, with a peak of 43 percent [1]. Every application system was disrupted for 11 minutes in report [5].

Why did tests not catch connection pool exhausted?

Post-release tests in report [4] found no major issue, and the leak appeared only when real traffic arrived. In report [3], no pooler saturation was visible until the flag reached 100 percent of pods.

Which test class catches connection pool exhausted, and what does it miss?

Integration tests, load tests and canary checks are listed, all with the by-design label. A canary on part of the pods misses saturation of a pool that every pod shares.

Which public reports document connection pool exhausted?

Five primary reports from four organisations document it. They were published between 2020-11-25 [5] and 2026-06-08 [1].

Should a team roll back or fix forward when connection pool exhausted happens?

Reports [2] and [3] ended the impact by disabling the feature flag that controlled the new code. Report [5] freed connections by hand until the code was reverted. Report [4] fixed the code and redeployed it.

Release Incident Playbook (2026). Connection pool exhausted: symptoms, cause, and the test that catches it, content version 1.0.0. https://releasefailures.com/incidents/connection-pool-exhausted/. Accessed 2026-10-21.