From da8801f1504855f4f8838807c31a22d9c29b1e57 Mon Sep 17 00:00:00 2001 From: Prajna1999 Date: Tue, 7 Apr 2026 12:12:37 +0530 Subject: [PATCH 1/3] fix: conditional connection pool sizes for staging and development --- backend/app/core/db.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/backend/app/core/db.py b/backend/app/core/db.py index 510e9da74..3f4a2aa5b 100644 --- a/backend/app/core/db.py +++ b/backend/app/core/db.py @@ -11,9 +11,16 @@ def get_engine(): # Configure connection pool settings # For testing, we need more connections since tests run in parallel - pool_size = 20 if settings.ENVIRONMENT == "development" else 5 - max_overflow = 30 if settings.ENVIRONMENT == "development" else 10 - + pool_size = 5 + max_overflow = 10 + + if settings.ENVIRONMENT == "development": + pool_size = 20 + max_overflow = 30 + elif settings.ENVIRONMENT == "staging": + pool_size = 12 + # test it out + max_overflow = 0 return create_engine( str(settings.SQLALCHEMY_DATABASE_URI), pool_size=pool_size, From 646aa949f383e511d5488451a2652fdaf335fb5c Mon Sep 17 00:00:00 2001 From: Prajna1999 Date: Tue, 7 Apr 2026 12:14:11 +0530 Subject: [PATCH 2/3] bump pool size to 16 for redundancy --- backend/app/core/db.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/core/db.py b/backend/app/core/db.py index 3f4a2aa5b..91b0966ac 100644 --- a/backend/app/core/db.py +++ b/backend/app/core/db.py @@ -18,7 +18,7 @@ def get_engine(): pool_size = 20 max_overflow = 30 elif settings.ENVIRONMENT == "staging": - pool_size = 12 + pool_size = 16 # test it out max_overflow = 0 return create_engine( From 9d826471715bc18abe9af28f2d3b4017c24f20fe Mon Sep 17 00:00:00 2001 From: Prajna1999 Date: Thu, 9 Apr 2026 08:43:06 +0530 Subject: [PATCH 3/3] fix: logger to track checked out db connections --- backend/app/celery/celery_app.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/backend/app/celery/celery_app.py b/backend/app/celery/celery_app.py index 45364a72f..975948600 100644 --- a/backend/app/celery/celery_app.py +++ b/backend/app/celery/celery_app.py @@ -1,7 +1,7 @@ import logging from celery import Celery -from celery.signals import worker_process_init +from celery.signals import task_prerun, worker_process_init from kombu import Exchange, Queue from app.core.config import settings @@ -9,6 +9,24 @@ logger = logging.getLogger(__name__) +@task_prerun.connect +def log_pool_status(task: "celery.Task", **_: object) -> None: # type: ignore[name-defined] + """Log DB connection pool state before each task to detect connection leaks. + + If checked_out equals pool size right when a task starts, connections + are being held across tasks (likely across LLM API calls) and leaking. + """ + from app.core.db import engine + from sqlalchemy.pool import QueuePool + + pool = engine.pool + if isinstance(pool, QueuePool): + logger.info( + f"[pool] task={task.name} checked_out={pool.checkedout()} " + f"size={pool.size()} overflow={pool.overflow()}" + ) + + @worker_process_init.connect def warm_llm_modules(**_) -> None: """Import LLM service modules in each worker process right after fork.