upvote
rust-analyzer taking 2GiB of RAM per instance definitely hurts.

And I agree that efforts to reduce this are noble and warranted, but I worry about what doesn’t happen because of those optimisations. The rust tooling is just so-so good (and a better argument for the language than memory safety imo), so I support more efforts to be ergonomic over memory optimisation.

Even though rust-analyzer is often the largest memory process on my machine. (and I only have 24GiB of RAM).

reply
I wish it only took 2gb on my project. It regularly goes over 8gb, I started running it in a cgroup limited to 8gb so it gets killed when it goes over instead of causing problems for the rest of my system. Hits it all the time. I have 64 GB of ram, but my project uses docker to monitor games servers which are also ram hungry so it's still a huge problem when testing. RA acts like they expect to be the only thing running on your pc.
reply
It wasn't long ago RA was consuming over 24GB for my main workspace.

They've been working on memory use and it dropped to ~7.5GB for a while but the last couple of releases have been nudging up again - currently 9.4GB without major change in the workspace.

It becomes an obstacle on a 64GB machine given I work with multiple workspaces open e.g. for the crates I am using, example projects, other branches etc. so I have to start/stop it when I just want basic type-info/navigation. Trialling a different editor alongside my current one becomes prohibitive when it's going to want another 10GB for it's own RA instance.

99% of the code isn't changing so disk caching does seem like a no-brainer like back in the 90s with intellisense .ncb files... just without the regular corruptions though!

reply
> rust-analyzer taking 2GiB of RAM per instance definitely hurts.

It compresses well though on average, if you have something like zram (I think windows/mac do something similar). When you get multiple projects open each with their own rust analyzer though, it starts to bite

reply
I would think there has to be some decent middle ground like storing some structures on disk mmap'd and letting the kernel handle back pressure and caching
reply
Storing structures mmapp'd is actually very tricky. I have experimented with rkyv initially having this idea in mind, but gave up because the machinery just to power the archive types was causing complexity to explode. The thing with zero-deserialization frameworks is that they are very limited in what they can abstract away, and it gets ugly pretty quickly.

So I don't deny the idea, just stating that it's probably _significantly_ more complex to implement than it sounds.

reply
I can shed some light here! This is going to be longish comment, but hopefully by the end of it you should understand _why_ we decided to avoid using the disk initially, even if you don't agree with that decision.

Historically, the decision to not use disk traces back to this comment https://github.com/rust-lang/rfcs/pull/1317#issuecomment-150..., which is perhaps the single GitHub comment that influenced my life most. Very high impact, thanks dgrunwald! Specifically,

>Don't store anything to disk. It's likely the oracle can be fast enough without doing this; and unnecessary complexity creates bugs. "Have you tried deleting the .ncb file?" (I remember having to do this a couple times per day when using VS, ca. 2005)

>Use lazy evaluation. The IDE is only interested in very specific bits of information, almost always restricted to a couple of lines around the cursor. Avoid calculating stuff that might never get used before it gets invalidated by the next code change.

>At least for C#, laziness saves so much time that incremental compilation is unnecessary for IDE purposes

The other part of historical context was that the motivation for creating rust-analyzer was that I didn't want to write a second Rust compiler (having been doing that for a couple of years at JetBrains). So it was explicitly an experimental project to prototype the right architecture for an IDE, to ultimately change how rustc works internally, so that, down the line, an IDE and a command-line compiler could use the same core. Given that rust-analyzer is now effectively a separate rust compiler, it's safe to say I am not good at achieving my life's goals!

In that context, I believe that avoiding disk was the _right_ decision:

* It's not really germane to the problem space, if all you need is literally a cache, it can always be added later.

* Disk is a can of worms of data consistency problems. They can be overcome with engineering effort to ultimately give better user experience, but user experience wasn't the primary goal. And using disk wouldn't actually illuminate the interesting aspects of the architecture, the intended primary goal.

* Finally, _not_ using disk would be a forcing function to keep analysis fast enough, to not make startup prohibitive.

The last one was a particularly big argument in my mind --- I didn't want to reach out for "easy" solutions prematurely, to avoid avoiding hard problems. And, again, my recollection is probably not 100% correct, but, until we added support for proc macros and build scripts, it was fine-ish from the perspective of startup time (RAM usage is a different story). The problem with proc_macros and build.rs is that they need to run the rust code, so they have to run the real rustc compiler, so all our usual IDE tricks ("information ... restricted to a couple of lines around the cursor") just don't apply.

The reason why we didn't add it later was that it seemed a relatively lower priority task than the work to share the parser between rust-analyzer and rustc. So that's what I was focusing on, though, I didn't deliver that. I still think we should do it! There's no _insurmountable_ technical reasons why the parsers can't be shared! It's just (a lot of) engineering work. And, while the parser is the boring part of compiler, it's the interesting part of an IDE.

Anyway, that explains how we ended up where we are.

That being said, I don't think that "just adding disk cache" is the right approach --- the salsa in-memory data structure is very sparse and pointy. Dumping that to disk would help somewhat, but wouldn't be a great long term solution. What is needed (I also explain this in https://matklad.github.io/2026/08/21/rust-glancer.html) is to design a compact, first class data format for representing analysis information about the crate, and than teaching rust-analyzer to be polymorphic in the source of data. For current workspace, you want to use a lazy incremental in-memory data structure (I do think we sadly need incrementally for Rust, given its compilation unit structure). For dependencies, you want to work off a compact on disk index. And, if the user "goes to definition" and mutates its file in place, we want to transparently switch between the two. The _pre requisite_ for that was to define a backend agnostic analysis API, and that work was always slowly progressing in the background (https://hackmd.io/ytd82QNiT_Ku2XFr1EAtiQ), but it generally took the backseat, while sharing the parser was the main focus.

reply
It would be nice if you could configure a maximum memory amount it's allowed to use. It regularly goes over 13gb in my large workspace so I have to configure it to run in a cgroup so it gets killed when it goes over 8gb or I can't run the other things on my desktop that I need to. I restart nvim after it crashes and it's back to around 6gb and working fine so it doesn't seem to need 13 GB to function. If it could handle that gracefully on it's own without cgroups/restarts that'd be a win. Regardless, thanks for your work on RA!
reply
Feels like you are missing the point a little bit. LSP is a human facing tool, so providing a good user experience should be the ultimate goal of it. What you described, feels to me, is not quite aligned with this goal.

Of course, since you describe RA as "explicitly an experimental project to prototype the right architecture for an IDE", all that doesn't matter and you can set the project's goal to be whatever you want. However, it just sucks for us, the users, because RA is the only thing we have. I'm just glad to see someone else is trying to do something different. And may the best project win.

reply
[flagged]
reply
The goal always was to refactor rustc to make compiler-based LSP feasible. The idea of original RLS, "we'll just use the compiler", is fundamentally sound. It's just that you'll need to turn the compiler sideways to achieve that, which is a hard work to motivate without having a real example demonstrating the benefits (or having political clout in the project to just mandate that ^^)
reply
[flagged]
reply
deleted
reply
deleted
reply