{"slug": "show-hn-drey-open-source-lsp-multiplexer-so-you-have-to-buy-less-ram", "title": "Show HN: Drey, open source LSP multiplexer so you have to buy less RAM", "summary": "Drey, an open-source LSP multiplexer, lets multiple editors and coding agents share a single language server per workspace to reduce memory usage, as demonstrated by two Claude Code sessions on one Rust workspace consuming 7.4 GB of RAM with separate rust-analyzer processes. The tool, installable via Homebrew or Cargo, intercepts LSP client requests and routes them through a daemon that pools real servers, swapping document states per client to handle unsaved edits correctly. Developer Mario claims Drey is early but tested, with architecture details available in the repository.", "body_md": "One language server per workspace, shared by every client.\n\nA drey is a squirrel's nest. This one is shared: many editors and coding agents crawl into a single indexed workspace instead of each digging their own.\n\nEvery LSP client starts its own language server. Two Claude Code sessions on one Rust workspace means two rust-analyzer processes, each holding a complete salsa database:\n\n``` bash\n$ footprint -p 36924   # session A\nphys_footprint: 3208 MB\n$ footprint -p 28845   # session B\nphys_footprint: 4225 MB\n```\n\nThat is 7.4 GB to answer questions about one copy of one codebase. Add a third session, or an editor alongside the agents, and it scales linearly. The same applies to gopls, tsserver, clangd, pyright and jdtls; Rust is the example because it is the one with the measurement.\n\ndrey makes them share.\n\n```\nbrew install mario/drey/drey     # macOS, brings its own Rust toolchain\ncargo install drey               # anywhere with a Rust toolchain\n```\n\nThen put drey in front of every language server on this machine, for every client at once:\n\n```\ndrey install                     # --dry-run first, if you want to see the plan\n```\n\nThat writes a wrapper named after each language server into `~/.drey/bin`\n\nand\nprepends it to `PATH`\n\n, so your existing clients pick drey up without being\nreconfigured. Open a new shell and check:\n\n```\nwhich rust-analyzer              # ~/.drey/bin/rust-analyzer\ndrey status                      # what is running, and who is attached\n```\n\nTo point one client at drey by hand instead, name `drey serve rust-analyzer`\n\nwherever that client currently names `rust-analyzer`\n\n.\n\n[docs/install.md](/mario/drey/blob/main/docs/install.md) covers configuring servers, watching what is\nrunning, uninstalling, and what to do when something looks wrong.\n\ndrey is one binary in two roles. The shim looks exactly like a language server on stdio. The daemon owns a pool of real servers, one per workspace, and autostarts on first use.\n\n```\n  Claude Code ──▶ drey serve ─┐\n  Codex       ──▶ drey serve ─┼──▶ daemon ──▶ one rust-analyzer\n  Helix       ──▶ drey serve ─┘\n```\n\nA client attaches to a running server when the server name and\n`initializationOptions`\n\nmatch and its workspace roots are *contained* in the\nroots already indexed. Containment rather than equality means opening a single\ncrate inside a Cargo workspace costs nothing: it attaches to the workspace\nalready in memory. Git worktrees and branches deliberately stay separate,\nbecause merging them would produce wrong answers, which is worse than using\nmemory.\n\nTwo clients with different unsaved edits to the same file still share one\nprocess. Each document keeps the text everyone agrees on plus whichever client's\nedits the server is currently holding, and the daemon swaps that before\nanswering. Verified against a real rust-analyzer: with one client holding\n`pub size: u32`\n\nand another holding `u64`\n\n, the same process reports\n`size = 4, align = 0x4`\n\nto the first and `size = 8, align = 0x8`\n\nto the second.\nThat is a type layout recomputed per client, not an echo of the text they sent.\n\n[docs/architecture.md](/mario/drey/blob/main/docs/architecture.md) explains the three ideas the design\nrests on, and the parts that were harder than they look.\n\nEarly. It works and it is tested, but it has been exercised against a mock server far more than against every real one.\n\nThe state swapping rests on an assumption worth stating plainly. It needs the server to process messages in order, which every LSP server must, and to either snapshot per request (rust-analyzer does) or answer before the next swap arrives. A server that batches work across messages could in principle answer against a state that has since moved. If you hit that, lowering the thrash threshold makes such a client fork instead.\n\nA swap also resends full document text rather than an incremental edit. That is cheap for source files and would not be for very large generated ones.\n\n[lspmux](https://codeberg.org/p2502/lspmux) does the same job and got there\nfirst; [lspmux-rust-analyzer](https://github.com/sunshowers/lspmux-rust-analyzer)\npackages it for this exact use case. drey exists because of the two things they\ndocument as out of scope: server-initiated requests are dropped there, and\ndocument divergence between clients is not reconciled.\n\nBug reports, patches and new server builtins are welcome. Read\n[CONTRIBUTING.md](/mario/drey/blob/main/CONTRIBUTING.md) first: it covers the checks CI runs on every\npull request, and what a change to sharing policy needs before it lands.\n\nApache License 2.0. Copyright 2026 Mario Đanić. See [LICENSE](/mario/drey/blob/main/LICENSE) and\n[NOTICE](/mario/drey/blob/main/NOTICE).", "url": "https://wpnews.pro/news/show-hn-drey-open-source-lsp-multiplexer-so-you-have-to-buy-less-ram", "canonical_source": "https://github.com/mario/drey", "published_at": "2026-07-22 06:54:44+00:00", "updated_at": "2026-07-22 07:22:37.780120+00:00", "lang": "en", "topics": ["developer-tools", "artificial-intelligence"], "entities": ["Drey", "Mario", "Claude Code", "rust-analyzer", "Homebrew", "Cargo", "LSP"], "alternates": {"html": "https://wpnews.pro/news/show-hn-drey-open-source-lsp-multiplexer-so-you-have-to-buy-less-ram", "markdown": "https://wpnews.pro/news/show-hn-drey-open-source-lsp-multiplexer-so-you-have-to-buy-less-ram.md", "text": "https://wpnews.pro/news/show-hn-drey-open-source-lsp-multiplexer-so-you-have-to-buy-less-ram.txt", "jsonld": "https://wpnews.pro/news/show-hn-drey-open-source-lsp-multiplexer-so-you-have-to-buy-less-ram.jsonld"}}