Skip to content

Memory growth in River UI after #242 deploy #246

@sanity

Description

@sanity

Report

Ivvor on Matrix (2026-05-14, post-#242 deploy):

Latest River is going through memory like crazy

Filing as a separate issue from the rotation bug (#245 fixes that one) since the memory behaviour is independent of the secrets back-fill.

What we don't know yet (please update if reproducible)

  • Whether it's the browser tab's heap or somewhere else (Freenet node memory? Chat-delegate state?)
  • Whether it grows monotonically vs spikes on specific actions (send message, room switch, member set change)
  • Whether disabling private rooms / private-room creation makes it go away

Suspects, ordered by likelihood

  1. Repeated delegate rotation churn. The fix(delegate): back-fill prior secret versions for newly-joined members #245 fix re-emits encrypted_secrets for newly-joined members at every version; on a long-lived room with many rotations this is O(versions × members) per join. Probably fine, but worth measuring.
  2. Chat-delegate state retention. PR feat: move private-room secret rotation into chat delegate (#228 PR 2) #235 added per-room delegate state (signing keys, member set caches, per-version secret cache at secret_keys::secret(room, v)). The per-version secret cache grows unboundedly — there's no GC for old versions.
  3. Re-render loops on ROOMS signal mutations. PR feat(ui): re-enable private room creation (#228 Phase 4) #239 added private-room UI surfaces. A signal that fires too eagerly during rotation propagation could trigger render storms.
  4. In-room DM state accumulation. PR feat(common): in-room encrypted direct messages between members (#230 Phase 1) #240 added DirectMessagesV1 (currently empty in production since Phase 2 UI is not shipped). The direct_messages: DirectMessagesV1 { messages: [], purges: [] } field appears in every state update; if something is cloning the whole state for each update, the empty vecs get allocated repeatedly. Cheap individually, but accumulation possible.
  5. Subscription leak. The EnsureRoomSubscription once-per-session dedup in ui/src/components/app/chat_delegate.rs:162 is per-session, but the underlying subscription on the node side might be leaking handles.

Repro ideas (need Ivvor or a fresh tester)

  1. Open River, take a heap snapshot in DevTools.
  2. Create a private room, invite a peer (use fix(delegate): back-fill prior secret versions for newly-joined members #245 build).
  3. Exchange ~10 messages.
  4. Take another heap snapshot.
  5. Compare — what objects are growing? Retained size by class?

If easy: a 5-minute screen recording of chrome://process-internals/ showing the tab's RSS over time would tell us a lot.

Relates to

[AI-assisted - Claude]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions