perf: use channel.purge() instead of per-message delete loops #93

Closed
opened 2026-03-20 13:17:41 +00:00 by cal · 1 comment
Owner

Problem

Multiple locations iterate channel history and call message.delete() in a loop — each delete is a separate Discord API call subject to rate limiting (5/sec per channel).

commands/admin/management.py lines 572–578 (admin_clear_scorecards)

async for message in live_scores_channel.history(limit=100):
    try:
        await message.delete()
        deleted_count += 1
    except discord.NotFound:
        pass

Up to 100 individual API calls. Note: admin_clear in the same file already correctly uses channel.purge().

tasks/live_scorebug_tracker.py lines 192–193, 220–221

Both _post_scorebugs_to_channel and _clear_live_scores_channel delete messages one at a time in a channel.history(limit=25) loop. This runs every 3 minutes on the update cycle.

Fix

deleted_messages = await channel.purge(limit=100)
deleted_count = len(deleted_messages)

channel.purge() uses Discord's bulk delete API — one request for up to 100 messages. Note: only works for messages under 14 days old; if older messages are possible, add a check parameter.

Impact

MEDIUM — The scorebug tracker runs every 3 minutes and adds several seconds of unnecessary latency to each cycle. Admin command goes from ~20 seconds to ~1 second for 100 messages.

## Problem Multiple locations iterate channel history and call `message.delete()` in a loop — each delete is a separate Discord API call subject to rate limiting (5/sec per channel). ### `commands/admin/management.py` lines 572–578 (`admin_clear_scorecards`) ```python async for message in live_scores_channel.history(limit=100): try: await message.delete() deleted_count += 1 except discord.NotFound: pass ``` Up to 100 individual API calls. Note: `admin_clear` in the same file already correctly uses `channel.purge()`. ### `tasks/live_scorebug_tracker.py` lines 192–193, 220–221 Both `_post_scorebugs_to_channel` and `_clear_live_scores_channel` delete messages one at a time in a `channel.history(limit=25)` loop. This runs every 3 minutes on the update cycle. ## Fix ```python deleted_messages = await channel.purge(limit=100) deleted_count = len(deleted_messages) ``` `channel.purge()` uses Discord's bulk delete API — one request for up to 100 messages. Note: only works for messages under 14 days old; if older messages are possible, add a check parameter. ## Impact **MEDIUM** — The scorebug tracker runs every 3 minutes and adds several seconds of unnecessary latency to each cycle. Admin command goes from ~20 seconds to ~1 second for 100 messages.
cal added the
ai-working
label 2026-03-20 13:18:39 +00:00
cal removed the
ai-working
label 2026-03-20 13:21:33 +00:00
Claude added the
ai-working
label 2026-03-20 17:01:05 +00:00
Claude removed the
ai-working
label 2026-03-20 17:02:53 +00:00
Collaborator

PR #108 opens the fix: #108

Replaced all three async for message in channel.history(): await message.delete() loops with await channel.purge() — one bulk API call instead of up to 100 individual ones. Tests: 935 passed.

PR #108 opens the fix: https://git.manticorum.com/cal/major-domo-v2/pulls/108 Replaced all three `async for message in channel.history(): await message.delete()` loops with `await channel.purge()` — one bulk API call instead of up to 100 individual ones. Tests: 935 passed.
Claude added the
ai-pr-opened
label 2026-03-20 17:03:00 +00:00
cal closed this issue 2026-03-20 17:44:30 +00:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: cal/major-domo-v2#93
No description provided.