Two of the daemon's lookaside tables grow with traffic and are never pruned #139

Closed
opened 2026-09-07 17:52:36 -04:00 by Salastil · 1 comment
Owner

The problem

Two of the runtime's lookaside tables grow with how much has happened rather
than with how much is in use, and nothing takes an entry out again:

  • discord_members - one JSON member object per (guild, user) ever seen in a
    member window. Scrolling a large guild's member list puts thousands in, and
    they stay for the life of the process.
  • matrix_reaction_targets and matrix_own_reactions - one entry per
    reaction event seen. take_matrix_reaction_target removes an entry when a
    redaction resolves against it, which is the minority of reactions; its doc
    comment claims this keeps the map from growing unboundedly, and it does not.

Small in absolute terms next to the arena finding above - a few megabytes -
so this is hygiene rather than the cure. Filed because it is exactly the shape
of thing that becomes the cure on a machine left running for a week.

The solution

A ceiling of 5,000 entries on each, applied on insert by a shared cap_cache
helper: past it, three quarters of the table is kept and the rest goes.

Which entries go is not chosen. A HashMap has no order to call oldest, and
keeping one would cost a second structure on every insert to save a lookup
that already knows how to fail - so the trade is deliberate and written down:
this may drop something in use, and what happens then is one more request.
Both tables are caches with a miss path.

Fixed in nobilis dbbc483 "Hold less of what a long day leaves behind", with a
test.

## The problem Two of the runtime's lookaside tables grow with how much has happened rather than with how much is in use, and nothing takes an entry out again: - `discord_members` - one JSON member object per (guild, user) ever seen in a member window. Scrolling a large guild's member list puts thousands in, and they stay for the life of the process. - `matrix_reaction_targets` and `matrix_own_reactions` - one entry per reaction event seen. `take_matrix_reaction_target` removes an entry when a redaction resolves against it, which is the minority of reactions; its doc comment claims this keeps the map from growing unboundedly, and it does not. Small in absolute terms next to the arena finding above - a few megabytes - so this is hygiene rather than the cure. Filed because it is exactly the shape of thing that becomes the cure on a machine left running for a week. ## The solution A ceiling of 5,000 entries on each, applied on insert by a shared `cap_cache` helper: past it, three quarters of the table is kept and the rest goes. Which entries go is not chosen. A `HashMap` has no order to call oldest, and keeping one would cost a second structure on every insert to save a lookup that already knows how to fail - so the trade is deliberate and written down: this may drop something in use, and what happens then is one more request. Both tables are caches with a miss path. Fixed in nobilis dbbc483 "Hold less of what a long day leaves behind", with a test.
Salastil added the buglow priority labels 2026-09-07 17:52:36 -04:00
Author
Owner

Finished - dbbc483a32

Finished - https://git.salastil.com/Salastil/nobilis/commit/dbbc483a32607bf036670b3ed2f0b8c515a0300b
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Salastil/moho#139