Skip to content

rust-analyzer: unbounded memory (40+ GB) on large Rust workspaces — hardcoded heavyweight init options #1556

Description

@davidcforbes

Preconditions:

  • I have made sure it's an actual issue, not a question (use GitHub Discussions instead).
  • I have consulted the user guide and verified that the issue cannot be resolved by adjusting configuration/following recommended workflows.
  • I have looked for similar issues and discussions, including closed ones.

Issue details:

  • I have provided a meaningful title and description.
  • I have explained how the issue arose and, where possible, added instructions on how to reproduce it.
  • I have added details on my setup: Serena version, MCP client, OS, the programming language(s), relevant configuration adjustments and project specifics.
  • If the issue relates to an application of Serena to an open-source project, I have added the link.

Summary

On a large, actively-built Rust workspace, the rust-analyzer process Serena launches repeatedly grew to 40–44 GB RAM — with no editor (VS Code/JetBrains) running. Serena's MCP server was the only thing keeping rust-analyzer engaged.

Environment

  • Serena 1.5.4.dev0 (git main), Windows 11, MCP server launched via uvx --from git+https://github.com/oraios/serena serena.
  • Workspace: a multi-crate Rust workspace (~10 crates) with a path-dependency on a vendored fork of a large crate and a sibling UI crate — i.e. a large dependency graph.
  • The workspace is built continuously from a terminal (cargo build / cargo test) while Serena is connected.

Root cause

src/solidlsp/language_servers/rust_analyzer.py launches rust-analyzer with VS Code's full heavyweight initializationOptions, hardcoded, with no knob to tune them down. Two of these are not needed by Serena's symbol tools (find_symbol, find_referencing_symbols, get_symbols_overview, …) and are exactly what drives the resident memory on a big workspace:

Option Value Effect
cachePriming.enable true Eagerly indexes the entire workspace + all dependencies at startup — the dominant contributor to the 40 GB resident set
cargo.autoreload true Re-indexes on every target/ / Cargo metadata change — so each external cargo build triggers a re-index storm

Impact

  • 40–44 GB rust-analyzer processes with no editor present.
  • Continuous re-indexing whenever the project is built outside Serena.
  • No configuration option to mitigate; the heavy options are hardcoded.

Proposed fix

Run rust-analyzer in a symbol-navigation-oriented lightweight profile by disabling the two eager/auto re-indexing drivers, while leaving diagnostics intact:

"cachePriming": {"enable": False, "numThreads": 0},   # was True
"cargo": { "autoreload": False, ... },                # was True
# checkOnSave is intentionally LEFT True (see note)

Why checkOnSave must stay enabled

It is tempting to also disable checkOnSave for a lightweight profile, but doing so breaks Serena's get_diagnostics_for_file for Rust. rust-analyzer's diagnostics for ordinary errors (e.g. an unresolved name → E0425) are produced by flycheck (cargo check); with checkOnSave: false Serena's pull-diagnostics request comes back empty. This is covered by test/solidlsp/rust/test_rust_diagnostics.py::test_file_diagnostics, which fails with [] when checkOnSave is off and passes when it is on. checkOnSave only spawns transient cargo check child processes — it is not a driver of rust-analyzer's resident RSS — so keeping it on preserves diagnostics at no meaningful memory cost.

Ideally these would be exposed as a config toggle (e.g. per-language language_server_options, or a global lightweight / symbol_only flag) rather than hardcoded, so users who want the full RA feature set can opt in.

Repro

  1. Open Serena on a large multi-crate Rust workspace (no editor running).
  2. Build the workspace repeatedly from a terminal (cargo build / cargo test).
  3. Watch rust-analyzer RSS climb to tens of GB and re-index on each build.

Fix

A PR implementing the lightweight profile (disable cachePriming + cargo.autoreload, keep checkOnSave) follows.

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