OpenHands / OpenHands/enterprise

DB connection pool defaults too high and not env-tunable, exhausting Postgres in distributed deploys

Open
#60 1 comment 0 reactions 1 assignee View on GitHub

@dylan-openhands is already working on this.

Since Jul 14, 2026.

Dominant language
Python
Stars
4
Forks
2
Avg merge
1d 22h
Merged PRs (30d)
101

Description

Problem

DbSessionInjector (openhands/app_server/services/db_session_injector.py) defaults to pool_size=25 — 5× SQLAlchemy's default of 5 — and pool_size/max_overflow are not wired to any env var, so they can't be tuned without a code change.

Every process holds its own pool, so total connections scale as pool_size × workers × replicas. At pool_size=25 you can only run floor(max_connections / 25) processes before the idle floor alone saturates Postgres (4 processes on a default max_connections=100; 60 at 1,500).

Impact

In a production setting (15 replicas × 3 workers = 45 processes) this held ~1,125 idle connections at all times with a ~1,575 burst ceiling against Cloud SQL max_connections ≈ 1,500 — before other clients — surfacing as sqlalchemy.exc.TimeoutError: QueuePool limit of size 25 overflow 10 reached. Observed 30-day p95: active ≈ 1.5, idle ≈ 752, i.e. ~100× over-provisioned.

Fix

  • Lower the pool_size default 25 → 5 (align with SQLAlchemy; max_overflow stays 10).
  • Read DB_POOL_SIZE / DB_MAX_OVERFLOW from env (same names the Alembic runner already uses) so deployments can tune pooling without code changes.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.