Product
Platform Agentic Code Scanner Unified Runner Tomosu Agents Indexes Solutions
Get Started
Scan your repo VS Code plugin Tomosu MCP GitHub App CodeRabbit FAQ
Resources
Case Studies Governance Impact TCO Calculator Download / Free Trial
Company
About Blog Production Reliability series Production Debugging guides AI Observability News Contact Request Demo →
Case study · IBM ContextForge

3,000 users exposed it. Could the code have told us first?

Tomosu AI·7 min read·

On January 3, 2026, a 3,000-user load test against IBM ContextForge left PostgreSQL connections stuck in idle in transaction until the pool ran dry. The cause was three lines of cleanup code. We rewound the repository to the code as it stood before the fix, gave Tomosu that one file and nothing else, and ran a blind scan. Tomosu named the same weakness and proposed a fix that makes connection release unconditional.

42–81connections stuck idle in transaction
120 sheld before a timeout released them
27 / 100PRI on the blind scan, Critical
Direct hitagainst a criterion locked before scanning
Summary

A connection leak that took a 3,000-user load test to expose was also identifiable from the application source alone.

The system under test

ContextForge is an open-source AI gateway and registry for MCP, A2A, REST and gRPC. AI agents, applications and copilots call it, and it routes, authenticates, scopes tokens and federates tools to downstream servers. Every request opens a database session against a PostgreSQL connection pool with bounded capacity. That puts it squarely in a high-concurrency path.

What the load test found

The team ran a test with 3,000 concurrent users, designed to expose behaviour that never appears during ordinary development. Requests looked healthy, but PostgreSQL connections stopped cycling normally. Between 42 and 81 connections sat in idle in transaction: occupied, doing no useful work, and unavailable for reuse. Each one could stay stuck for up to 120 seconds before a timeout intervened. Two minutes is an eternity when thousands of requests are competing for a limited pool.

Each stage of the failure is ordinary. The amplification is not.

  1. 3,000 concurrent requests arrive
  2. Each opens a database session from a finite pool
  3. Some connections are never released
  4. The pool runs out of capacity
  5. Latency, errors and upstream cascading failures

The code: a cleanup that wasn't guaranteed

The investigation led to the session cleanup in token_scoping.py. It looks reasonable: a finally block, a commit, a close. The intent is clearly to clean up the session whatever happened earlier.

Vulnerablemcpgateway/middleware/token_scoping.py
finally:
    db.commit()   # can raise
    db.close()    # never reached if commit raises

But finally does not mean every statement inside it is guaranteed to run. db.commit() is itself an operation that can fail. If it raises, Python leaves the block immediately and execution never reaches close(). Three lines, under enough concurrency, become pool exhaustion.

The fix: make release unconditional

PR #1886 nests the commit in its own try so the close survives a failing commit. The implementation change is tiny. The conceptual change is not.

FixPR #1886
finally:
    try:
        db.commit()
    finally:
        db.close()   # always runs

Under the same 3,000-user load, the result changed completely:

Before the fixAfter the fix
Stuck connections42–810
Connection releaseHeld up to 120 sCycling in 1–2 s
Pool stateExhaustedHealthy

The rule underneath it: if you acquire a finite production resource, its release must survive every relevant failure path.

The experiment: could Tomosu have caught it first?

Everything the team learned came from production-scale conditions. We wanted to know whether Tomosu could surface the same weakness from the code, before any load test. We were not asking Tomosu to review the patch. We checked out commit cf5adcd5d, the code exactly as it stood before the remediation existed, and gave Tomosu one file: mcpgateway/middleware/token_scoping.py, 755 lines, 32 KB.

Before scanning, we locked the success criterion so the result could not be reinterpreted afterwards:

Success criterion, sealed before the scan

Identify unsafe database-session cleanup where an operation before close() can fail and prevent reliable connection release.

Direct hit: names the unsafe session lifecycle on this path. Adjacent: generic exception-handling or database advice. Miss: anything else.

The result: a direct hit

Tomosu blind scan of contextforge-production-scan: scan complete, 1 file, 1 minute 41 seconds, 5 issues, Production Reliability Index 27 out of 100, rated Critical
The blind scan: 1 file, 1m 41s, 5 issues, PRI 27 / 100, Critical. Tomosu was not told this was an IBM bug, that a load test existed, that connections were stuck, or what kind of issue to look for.
High severity · Graceful cleanup · Resource lifecycle

Unsafe database-session lifecycle

“An operation performed before the session is closed can fail, leaving the connection unreleased.”

Scored against the locked criterion, the finding names the database-session cleanup path, states that the preceding operation can fail, and ties it to unreliable connection release. All three checks pass.

Finding on token_scoping.py, identified from the historical source alone, with no incident context.

Tomosu's recommended change removes the commit from the cleanup entirely, because this is a read-oriented path that needs no commit. Connection release becomes unconditional.

Three versions, one invariant

Vulnerable
finally:
    db.commit()
    db.close()
Release depends on commit
IBM fix
finally:
    try:
        db.commit()
    finally:
        db.close()
Commit kept, close protected
Tomosu, blind
finally:
    db.close()
Commit dependency removed

Different code, same reliability property: release must not depend on commit succeeding. Tomosu had not seen the patch.

Two paths to the same weakness

One path ran a 3,000-user load test, observed the failure, investigated and located the defect. The other read the historical source and identified the weakness with no incident context. Static analysis does not replace load testing. It moves some of the learning earlier, to the pull request, where fixing it costs three lines instead of an outage.

Reliability is a lifecycle, not a one-time code review. Resource-lifecycle analysis in code, readiness context at deploy, production signals at runtime, and runtime insight fed back into the next change.

Get the full forensics deck
22 slides, PDF

Download the deck

ContextForge is an open-source project. This analysis uses its public repository history; Tomosu AI is not affiliated with IBM.


What will your load test find, and could your code tell you first? Run a free PRI scan on any GitHub repository.