From 35763a352c43fae605130a4ad13453329bc77d1c Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Thu, 19 Feb 2026 22:50:03 +0100 Subject: [PATCH] Optimize shared chats list to use column projection (#163) (#21614) The GET /chats/shared endpoint was loading full Chat rows including the entire conversation history JSON blob, only to discard it and return SharedChatResponse (id, title, share_id, timestamps). Now uses with_entities() to select only the 5 needed columns, avoiding deserialization of potentially large chat JSON for every shared chat. --- backend/open_webui/models/chats.py | 20 ++++++++++++++++++-- backend/open_webui/routers/chats.py | 19 +++++++------------ 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/backend/open_webui/models/chats.py b/backend/open_webui/models/chats.py index 1418abd62..89148f08b 100644 --- a/backend/open_webui/models/chats.py +++ b/backend/open_webui/models/chats.py @@ -754,7 +754,7 @@ class ChatTable: skip: int = 0, limit: int = 50, db: Optional[Session] = None, - ) -> list[ChatModel]: + ) -> list[SharedChatResponse]: with get_db_context(db) as db: query = ( @@ -784,13 +784,29 @@ class ChatTable: else: query = query.order_by(Chat.updated_at.desc()) + # Select only the columns needed for SharedChatResponse + # to avoid loading the heavy chat JSON blob + query = query.with_entities( + Chat.id, Chat.title, Chat.share_id, + Chat.updated_at, Chat.created_at, + ) + if skip: query = query.offset(skip) if limit: query = query.limit(limit) all_chats = query.all() - return [ChatModel.model_validate(chat) for chat in all_chats] + return [ + SharedChatResponse( + id=chat[0], + title=chat[1], + share_id=chat[2], + updated_at=chat[3], + created_at=chat[4], + ) + for chat in all_chats + ] def get_chat_list_by_user_id( self, diff --git a/backend/open_webui/routers/chats.py b/backend/open_webui/routers/chats.py index 69e47123f..e04c23496 100644 --- a/backend/open_webui/routers/chats.py +++ b/backend/open_webui/routers/chats.py @@ -887,18 +887,13 @@ async def get_shared_session_user_chat_list( if direction: filter["direction"] = direction - chat_list = [ - SharedChatResponse(**chat.model_dump()) - for chat in Chats.get_shared_chat_list_by_user_id( - user.id, - filter=filter, - skip=skip, - limit=limit, - db=db, - ) - ] - - return chat_list + return Chats.get_shared_chat_list_by_user_id( + user.id, + filter=filter, + skip=skip, + limit=limit, + db=db, + ) ############################