Skip to content

fix: eliminate search OOM stampede + share slug cache across sessions (v5.2.1)#14

Merged
ttpears merged 1 commit into
mainfrom
fix/search-slug-stampede-oom
Jul 20, 2026
Merged

fix: eliminate search OOM stampede + share slug cache across sessions (v5.2.1)#14
ttpears merged 1 commit into
mainfrom
fix/search-slug-stampede-oom

Conversation

@ttpears

@ttpears ttpears commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Why

Users reported the BookStack connector (deployed to Swarm at bookstack-mcp.teamgleim.com) being buggy and slow. Investigation found two related issues on the shared, rate-limited (180 req/min) BookStack service token:

  1. OOM crashes (already live via the branch image, now landed on main): enhancing search/recent/list results resolved a book slug per item via a non-atomic check-then-set cache, so a batch stampeded GET /books/{id}, BookStack 429'd the burst, retries piled up, and the Node heap OOM-crashed the container (exit 134 / "Reached heap limit"). Fixed by bulk-warming the slug cache from one /books listing + in-flight dedup, plus a configurable axios timeout. (commit 861796d)

  2. Intermittent long stalls (this release's new fix): the warm cache lived on each BookStackClient, and index.ts builds one client per MCP session, so every new session re-ran the /books sweep. Those redundant sweeps burned the shared 180/min budget and, under concurrent use, tripped 429s whose Retry-After (12–47s) blocked requests. Moved the slug cache (+ in-flight dedup + warm promise) to a process-wide store keyed by base URL, refreshed at most once per 10-min TTL. One sweep per process/TTL instead of one per session. (commit 4b72cdd)

Verification

  • npm run type-check and npm run build clean.
  • One-off test (mock BookStack counting /books sweeps): two client instances (= two sessions) now share 1 sweep (was 2), slug still resolved correctly.

Notes

  • 429 retry behavior intentionally unchanged (still honors full Retry-After).
  • Also bumps .claude-plugin/plugin.json (was stale at 5.1.0) to 5.2.1.
  • Releasing as 5.2.1 supersedes the never-tagged :5.2.0 (which only ever existed as a branch-built image); this PR finally lands the OOM fix on main.

…ed token

The book-slug warm cache lived on each BookStackClient instance, and index.ts
builds one client per MCP session, so every new session re-ran the bulk /books
sweep on its first search. All sessions share ONE BookStack service token whose
API rate limit is 180 req/min, so the redundant per-session sweeps burned that
shared budget and, under concurrent use, tripped 429s whose Retry-After (12-47s)
blocked requests — surfacing as intermittent long stalls even after the OOM fix.

Move the slug cache (plus the in-flight dedup and warm promise) to a process-wide
store keyed by base URL, refreshed at most once per 10-minute TTL. The book-id to
slug mapping is identical for all callers of the same BookStack regardless of
token, so sharing is safe. Turns N per-session sweeps into one per process/TTL.

Also bumps plugin.json (was stale at 5.1.0) and version to 5.2.1.
@ttpears
ttpears merged commit 1f87189 into main Jul 20, 2026
3 checks passed
@ttpears
ttpears deleted the fix/search-slug-stampede-oom branch July 20, 2026 19:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant