Join the discussion

Write your take first — we'll ask for email only when you're ready to publish.

  • Hacker News
  • This is music to my ears. Going to try this now.
  • Will give it a shot and loved the "LLMs were used as a tool, not as a brain replacement"
  • Good work, though can't help but think that when something that isn't just a small hack where perf doesn't matter can be made "100x faster", it tells more about the original work than the new thing :D
  • Not 100x faster, but 100x less memory. In fact, this version is actually slower for some use cases.

    Everything is a trade off.

  • this is awesome and I hope this gains some real steam, we're building everything in rust and locally if i'm watching youtube and running a build+tests and my vscodium starts running the analyzer at the same time I've seen my machine stutter out as it eats up the memory.
  • Can you tell about how you write/read your data to/from disk? I‘m also exploring the incremental world using an approach like salsa+rocksdb. Similar like https://docs.rs/qbice/latest/qbice/. Would be great to learn about your approach.
  • And regarding salsa+rocksdb, actually Alex Kladov advocated exactly for that in the post about Rust Glancer and rust-analyzer architecture: https://matklad.github.io/2026/08/21/rust-glancer.html

    Though I believe it's more of a direction for rust-analyzer rather Rust Glancer, at least for now.

  • Well, it's hard to give a concise overview, but in short -- I use `wincode` for serde (without zero-copy deserialization though; I've tried zero-copy first with rkyv but it was not trivial at all so I abandoned this idea, plus FS does not dominate the costs so far anyway).

    Data is written at the end of indexing phase, during write we hold a lock, and the codebase is aware that offloaded data can be corrupted/outdated (mostly relevant for cache).

    Query processing works on top of transaction, and the transaction holds data loaded from files for the duration of the query, and frees once the query is dropped.

    There is a ton of tricky parts there, but I guess that's the gist of it.

    If you're interested, here are the relevant parts of the source code: https://github.com/rust-glancer/rust-glancer/tree/main/crate... https://github.com/rust-glancer/rust-glancer/tree/main/crate... https://github.com/rust-glancer/rust-glancer/blob/main/crate... https://github.com/rust-glancer/rust-glancer/blob/main/crate...

  • While I respect the work behind rust-analyzer greatly and think it's a good part of how cool the language is, I will NEVER understand the design decision to flat out refuse using disk cache. I understand the argument that implementing this puts less pressure behind speeding up the indexing process, but honestly with the price of ram today I'm tired of the memory and cpu usage each rust-analyzer process takes up. Especially since we do more and more parallel work.

    I honestly think it's the wrong philosophy. Once again I'm a nobody compared to maintainers, so take my opinion with a grain of salt

  • 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).

  • 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.

  • This is coming full circle back to how `rust-analyzer` originally got introduced: it was an alternative to the official `rls` (Rust lanaguage server) intended to provide better performance and eventually became the new official one. I've seen enough issues with rust-analyzer in the wild with coworkers having trouble getting it working well for their setups that I'm open to the idea that an alternative might be needed again, but I can't help but also be disappointed that we've gotten to this point yet again (not blaming the author of this tool of course; they're not the cause, just responding to the symptom).
  • I personally don’t agree with “LLMs are just a tool” but I’m honestly impressed by the author’s description of LLM usage and taking the responsibility for the code. IMHO, without having looked at the code base itself, this sounds like a pretty healthy way to approach LLM usage!
  • "I personally don’t agree with “LLMs are just a tool”"

    Then what are they?

  • Hey! Author here. Happy to answer any questions.
  • please support the zed editor (pleading face emoji)
  • How come I can’t get no Tang around here?
  • Rust does not have a specification. How do you know your LSP is providing right information?
  • Super nice! Are you planning support for Zed editor?
  • Super cool!

    In the comparison table, you indicate indexing times. Could you also measure memory usage, since that's the stated goal of the project?

    by dbdr
  • Pretty cool! rust-analyzer takes such a huge amount of memory. Usually it’s not a problem but occasionally I’ve run into issues. Having an alternative, even with tradeoffs, is great.
  • Could you mind to tell me what is your plan on proc-macros ? You said you have an idea to “will not require actual code execution”. On the other hand, RA current method of handling in Proc-Macros are very fragile.
  • Could you elaborate a bit on why RA's incremental approach takes more memory? Intuitively it feels that it should take less, because you're only processing what you need? Whereas you seem to indicate that you save a full analysis snapshot to disk and load it all up when needed? Shouldn't that consume the max memory for a workspace?

    Fantastic project btw, and it couldn't come at a better time. With the way prices are going I really hope people start paying attention to memory again.

  • Tangential, but I've found something LLMs are actually ridiculously good at is making LSP servers.

    I couldn't find good TLA+ bindings for Neovim, so I got Claude to hack together an LSP server for it [1]. It works shockingly well, and it only took about an hour of arguing with Claude to do it.

    I find it's not terribly good at actually writing TLA+ (with some very recent tests with Fable), so I'm not completely useless yet.

    [1] https://github.com/Tombert/TLA-Language-Server-Protocol

  • The LSP spec is hideously complicated and has weird edge cases around what exactly is a newline, what content-encoding is used for counting offsets, and timing of events. I'd be very surprised if Claude got those right.

    My experience so far says that without subject-matter-expert prompting, Claude will take shortcuts with a naive "\r?\n" regexp etc.

    I would happily let Claude write tests for the various newline formats and content-encodings, though.

  • I would say that LLMs have really good understanding of LSPs, but they are not necessarily good at building them. Had I blindly followed the proposed flow, Rust Glancer wouldn't have reached a stage where it is at least remotely usable. At some point the size of the project becomes too big for LLM to fit in its context window, and with the tendence to add code rather than remove, the bloat can explode really quickly. At a pretty early stage, I did not catch a situation where LLM suggested an extremely stupid design (because I wasn't familiar with the scope enough at the moment), and it implemented a whole new parallel hierarchy of functionality that was already implemented but in a _slightly different_ form. When I realized it, it took nearly two weeks to unfuck the situation.

    So all in all -- yeah, LLMs can be good _domain experts_ when you build an LSP, but a) I wouldn't trust them blindly, and b) the quality of code is still very much your responsibility.