Skip to content

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

@davidcforbes

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions