From d02e826c9d1a3dea13947c3dd8e307a7e90a18ec Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Thu, 12 Feb 2026 01:20:03 +0100 Subject: [PATCH] Fix idle in transaction leaks in Open WebUI (#20868) * fix: add ScopedSession.remove() to prevent idle transaction leaks The HTTP middleware was calling ScopedSession.commit() but not ScopedSession.remove(), causing database connections to remain "checked out" from the pool indefinitely. This resulted in "idle in transaction" connections in PostgreSQL that could persist for 30-50+ minutes. With SQLAlchemy's scoped_session: - commit() commits but keeps the session active - remove() is required to return the connection to the pool This fix adds the missing remove() call, ensuring connections are properly returned after each HTTP request. Also includes IDLE_TRANSACTION_ANALYSIS.md documenting the full root cause analysis and additional recommendations. * Delete IDLE_TRANSACTION_ANALYSIS.md --------- Co-authored-by: Claude --- backend/open_webui/main.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 1c59a7b42..a6e55e0ac 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -1384,7 +1384,13 @@ app.add_middleware(APIKeyRestrictionMiddleware) async def commit_session_after_request(request: Request, call_next): response = await call_next(request) # log.debug("Commit session after request") - ScopedSession.commit() + try: + ScopedSession.commit() + finally: + # CRITICAL: remove() returns the connection to the pool. + # Without this, connections remain "checked out" and accumulate + # as "idle in transaction" in PostgreSQL. + ScopedSession.remove() return response