From f119c3378981df50cc43e8ca7b2cbfd4031c38e4 Mon Sep 17 00:00:00 2001 From: Mateusz Mandera Date: Mon, 11 Aug 2025 02:37:57 +0800 Subject: [PATCH] delete_in_topic: Don't fetch .recipient for each message in a loop. The grouping logic in `do_delete_messages` calls `message.is_stream_message()` in a loop, which needs to access message.recipient. This is obviously super inefficient if .recipient hasn't been prefetched for the message objects. `delete_in_topic` is the only function that calls `do_delete_messages` with many messages, so this is the only spot we need to fix, to address the immediate bug. Of course a better improvement would be to fix `do_delete_messages` to do something smarter than naively accessing message.recipient in a loop. --- zerver/views/streams.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/zerver/views/streams.py b/zerver/views/streams.py index 7a2a950a35..cb96bc5130 100644 --- a/zerver/views/streams.py +++ b/zerver/views/streams.py @@ -1323,8 +1323,10 @@ def delete_in_topic( if time.monotonic() >= start_time + 50: return json_success(request, data={"complete": False}) with transaction.atomic(durable=True): - messages_to_delete = messages.order_by("-id")[0:batch_size].select_for_update( - of=("self",) + messages_to_delete = ( + messages.select_related("recipient") + .order_by("-id")[0:batch_size] + .select_for_update(of=("self",)) ) if not messages_to_delete: break