Skip to content

Comments

[AI-assisted] fix(history): add LRU eviction for groupHistories to prevent memory leak#2389

Merged
thewilloftheshadow merged 2 commits intoopenclaw:mainfrom
robbyczgw-cla:fix/issue-2384-grouphistories-memory-leak
Jan 26, 2026
Merged

[AI-assisted] fix(history): add LRU eviction for groupHistories to prevent memory leak#2389
thewilloftheshadow merged 2 commits intoopenclaw:mainfrom
robbyczgw-cla:fix/issue-2384-grouphistories-memory-leak

Conversation

@robbyczgw-cla
Copy link
Contributor

Summary

Adds automatic LRU-style eviction to history maps to prevent unbounded memory growth in long-running instances.

Problem

The groupHistories Map (and similar maps in Signal, WhatsApp, iMessage monitors) grows unbounded as users interact with more groups over time:

const groupHistories = new Map<string, HistoryEntry[]>();

While clearHistoryEntries() empties values, keys are never deleted. Growth is O(unique groups), causing slow but steady memory accumulation.

Solution

Added to src/auto-reply/reply/history.ts:

export const MAX_HISTORY_KEYS = 1000;

export function evictOldHistoryKeys<T>(
  historyMap: Map<string, T[]>,
  maxKeys: number = MAX_HISTORY_KEYS,
): void {
  if (historyMap.size <= maxKeys) return;
  const keysToDelete = historyMap.size - maxKeys;
  const iterator = historyMap.keys();
  for (let i = 0; i < keysToDelete; i++) {
    const key = iterator.next().value;
    if (key !== undefined) historyMap.delete(key);
  }
}

Called automatically in appendHistoryEntry() to bound map size. Uses Map's insertion order for LRU-like behavior.

Benefits

  • ✅ Bounds memory growth to ~1000 groups maximum
  • ✅ Minimal overhead (only runs when threshold exceeded)
  • ✅ Uses existing Map insertion order (no extra data structures)
  • ✅ Applies to all channel monitors using the shared history functions

Testing

  • ✅ Build passes (pnpm build)
  • ✅ Lint passes (pnpm lint)
  • 🔍 Lightly tested - verified eviction logic with manual testing

AI Disclosure

This PR was AI-assisted (Claude/Codex). The issue was discovered through automated code analysis comparing memory patterns across long-running instances.

Fixes #2384

@openclaw-barnacle openclaw-barnacle bot added the channel: telegram Channel integration: telegram label Jan 26, 2026
Add evictOldHistoryKeys() function that removes oldest keys when the
history map exceeds MAX_HISTORY_KEYS (1000). Called automatically in
appendHistoryEntry() to bound memory growth.

The map previously grew unbounded as users interacted with more groups
over time. Growth is O(unique groups) not O(messages), but still causes
slow memory accumulation on long-running instances.

Fixes #2384
@robbyczgw-cla robbyczgw-cla force-pushed the fix/issue-2384-grouphistories-memory-leak branch from ba92349 to 8e495db Compare January 26, 2026 21:09
@thewilloftheshadow thewilloftheshadow self-assigned this Jan 26, 2026
@thewilloftheshadow thewilloftheshadow merged commit 5c35b62 into openclaw:main Jan 26, 2026
22 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: telegram Channel integration: telegram

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Memory leak in groupHistories Map - keys never evicted

2 participants