From 3fc866117da65c4a3e05e1a2add40b193933fd97 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:32:40 +0100 Subject: [PATCH] fix(db): CRITICAL - prevent pool exhaustion in memory /reset (#20580) Remove Depends(get_session) from POST /reset to prevent catastrophic connection pool exhaustion. This endpoint was holding a SINGLE database connection while executing N PARALLEL embedding API calls via asyncio.gather(). For a user with 100 memories, this meant one connection blocked for potentially MINUTES (100 calls * 1-5 seconds each, even in parallel due to rate limits). A single user triggering /reset could completely starve the connection pool, causing QueuePool timeout errors across the entire application. The Memories.get_memories_by_user_id() function now manages its own short-lived session, releasing the connection immediately before the massive parallel embedding operation begins. --- backend/open_webui/routers/memories.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/routers/memories.py b/backend/open_webui/routers/memories.py index b05e0c7a7..3738d1681 100644 --- a/backend/open_webui/routers/memories.py +++ b/backend/open_webui/routers/memories.py @@ -157,8 +157,15 @@ async def query_memory( async def reset_memory_from_vector_db( request: Request, user=Depends(get_verified_user), - db: Session = Depends(get_session), ): + """Reset user's memory vector embeddings. + + CRITICAL: We intentionally do NOT use Depends(get_session) here. + This endpoint generates embeddings for ALL user memories in parallel using + asyncio.gather(). A user with 100 memories would trigger 100 embedding API + calls simultaneously. With a session held, this could block a connection + for MINUTES, completely exhausting the connection pool. + """ if not request.app.state.config.ENABLE_MEMORIES: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, @@ -175,7 +182,7 @@ async def reset_memory_from_vector_db( VECTOR_DB_CLIENT.delete_collection(f"user-memory-{user.id}") - memories = Memories.get_memories_by_user_id(user.id, db=db) + memories = Memories.get_memories_by_user_id(user.id) # Generate vectors in parallel vectors = await asyncio.gather(