Skip to content

Support shared LSP server instances across sessions #28673

@mingley

Description

@mingley

Problem

The rust-analyzer-lsp plugin (and any LSP plugin using the declarative lspServers config) spawns a new LSP server process per Claude Code session. For rust-analyzer, each instance independently loads and indexes the entire project, consuming 500MB–2GB+ of memory. Running multiple Claude Code sessions against the same project means multiple redundant instances of the same server, all holding duplicate indexes in memory.

Current Architecture

The LSP Manager:

  1. Reads lspServers config from the plugin manifest
  2. Spawns a child process per session via stdio
  3. Manages a 1:1 client-server lifecycle tied to the session

Stdio transport is inherently single-client — there's no mechanism to discover or reuse an existing server process.

Proposed Solution

Add an option for LSP server definitions to share a single server process across sessions working on the same project. Two possible approaches:

Option A: Socket-based transport with process reuse

Allow lspServers config to specify a socket transport:

"lspServers": {
  "rust-analyzer": {
    "command": "rust-analyzer",
    "transport": "socket",
    "socketPath": "/tmp/claude-lsp-rust-analyzer-{workspaceHash}.sock",
    "shared": true,
    "extensionToLanguage": { ".rs": "rust" }
  }
}

The LSP Manager would:

  1. Check if a server is already running (via PID file or socket probe)
  2. If running, connect as an additional client
  3. If not running, spawn the server and register the PID/socket for future sessions
  4. Reference-count connections — shut down the server when the last session disconnects

Option B: Managed daemon with multiplexing proxy

For LSP servers that only support stdio (like rust-analyzer), the LSP Manager could:

  1. Spawn a lightweight proxy that owns the stdio connection to the server
  2. Accept multiple client connections over a Unix socket
  3. Multiplex requests and demultiplex responses, maintaining per-client state for open documents

Minimum viable version

Even without full multiplexing, the simplest improvement would be:

  • Detect when another session already has an LSP server running for the same workspace root
  • Reuse that server's index/cache directory so startup is near-instant even if a new process is spawned
  • rust-analyzer supports --log-file and cache directories that could be shared

Impact

  • Memory savings scale linearly with concurrent sessions (easily 1–4GB reclaimed for typical Rust projects)
  • Faster session startup — no re-indexing when a warm server already exists
  • Applies to all LSP plugins, not just rust-analyzer

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions