rust-analyzer hangs at 100% CPU in PrimeCaches after 1.93.1

Author: chenyh1990Created Sep 12, 2026Updated Sep 16, 2026
LabelsBroken WindowC-bugI-hang

rust-analyzer version:

Working version: 1.93.1

First known affected version: 1.94.1

Also reproduced with: 1.97.1, 1.98.0

rustc version:

rustc 1.97.1

editor or extension:

VSCode

relevant settings:

Large Rust monorepo with approximately 736 crates.

The issue occurs during cache priming.

I also tested with:

json
"rust-analyzer.cachePriming.numThreads": 1

and the issue still reproduces.

repository link (if public, optional):

Private repository.

code snippet to reproduce:

The issue only reproduces in our large private monorepo, so I currently do not have a minimal reproduction.

Description

There appears to be a severe performance regression between rust-analyzer 1.93.1 and 1.94.1.

With 1.93.1, the workspace loads normally and cache priming eventually completes.

Starting from 1.94.1, rust-analyzer can get stuck indefinitely during cache priming with approximately 100% CPU usage.

I also reproduced the issue with 1.97.1 and 1.98.0.

The crate shown as the last crate in the progress indicator is not deterministic. For example, one run stopped around:

734/736 (validate_proto)

but other runs stopped at different crates near the end of the workspace.

The rust-analyzer process then remains at approximately 100% CPU without making further progress.

Profiling

I profiled the affected process with perf.

The profile shows that the CPU time is overwhelmingly spent in the PrimeCaches#3 worker.

With symbols resolved, the profile is:

99.55%    99.55%  PrimeCaches#3  rust-analyzer
             [.] syntax_bridge::to_parser_input::to_parser_input

 0.36%     0.00%  PrimeCaches#3  [kernel.kallsyms]
             [.] asm_sysvec_apic_timer_interrupt
 0.35%     0.00%  PrimeCaches#3  [kernel.kallsyms]
             [.] sysvec_apic_timer_interrupt
 ...

In particular, approximately 99.55% of sampled CPU cycles are spent in:

syntax_bridge::to_parser_input::to_parser_input

inside:

PrimeCaches#3

This appears to be CPU-bound rather than rust-analyzer simply waiting for I/O.

Comparison with 1.93.1

With 1.93.1, cache priming eventually completes. For example, the log contains:

2026-09-12T07:33:59.962612001Z WARN overly long loop turn took 714.964958ms: (event handling took 683.121163ms): PrimeCaches(End { cancelled: false }) (cancellation took None) (garbage collection took Some(31.784941ms))

The important part is:

PrimeCaches(End { cancelled: false })

which indicates that cache priming eventually reaches the end.

With the affected versions, cache priming does not reach the corresponding completion state and the process remains CPU-bound.

numThreads = 1

I also tested:

json
"rust-analyzer.cachePriming.numThreads": 1

The issue still reproduces.

Therefore, the problem does not appear to require multiple cache-priming worker threads.

Version boundary

The behavior can be summarized as:

1.93.1  -> works
1.94.1  -> hangs
1.97.1  -> hangs
1.98.0  -> hangs

Given the clear version boundary and the perf profile, I suspect a regression in the syntax/query/cache-priming path introduced between 1.93.1 and 1.94.1.

In particular, syntax_bridge::to_parser_input::to_parser_input seems worth investigating.

A full perf call graph can be provided if useful.