LSP plugins spawn eagerly regardless of file types in project

Status Closed — not planned
Reported on v2.1.29
Maintainer reply None cached
Activity 4 comments · opened Feb 1, 2026 · closed Mar 2, 2026

Summary

All enabled LSP plugins spawn immediately at session start, ignoring extensionToLanguage mappings in plugin configs. LSPs should start lazily when a matching file is first read or edited.

Environment

  • Claude Code version: 2.1.29
  • OS: Arch Linux 6.18.3

Steps to Reproduce

# 1. Create empty directory
cd $(mktemp -d)

# 2. Start Claude session
claude -p "hello"

# 3. Check running LSPs
pgrep -a "clangd|rust-analyzer|gopls|pyright"

Expected: No LSPs spawn (no matching source files)
Actual: All enabled LSPs spawn immediately

Test Results

Started session in directory with zero source files:

$ pgrep -a "clangd|rust-analyzer|gopls|pyright"
clangd --background-index
rust-analyzer
gopls
pyright-langserver --stdio

Behaviors Tested

| Scenario | Expected | Actual |
|----------|----------|--------|
| Session in empty dir | No LSPs spawn | All enabled LSPs spawn |
| Session in JS-only project | Only TS LSP spawns | All enabled LSPs spawn |
| Read a .rs file | rust-analyzer starts | Already running |
| Plugin disabled in settings | LSP doesn't spawn | ✓ Works correctly |

Temp Directory Pollution

LSPs create temp directories even when never used:

| LSP | Temp Dirs Created | Disk Usage |
|-----|-------------------|------------|
| pyright | 16 | 0 (empty) |
| proc-macro-srv (rust-analyzer) | 9 | 0 |
| intelephense (PHP) | 1 | 6.9MB |
| lua-language-server | 1 | 4.5MB |

Proposed Solution

Start LSPs lazily based on extensionToLanguage mappings:

  • When a file with a mapped extension is first read/edited, start the corresponding LSP
  • Respect the plugin config's extension mappings

Workaround

Disable unused LSP plugins in ~/.claude/settings.json:

{
  "permissions": {
    "plugins": {
      "lua-lsp@claude-plugins-official": false,
      "rust-analyzer@claude-plugins-official": false
    }
  }
}

---

Resource Impact

| LSP | Memory | Temp Disk | CPU at Idle |
|-----|--------|-----------|-------------|
| rust-analyzer | ~150MB | 0 | ~2% |
| clangd | ~100MB | 0 | ~1% |
| pyright | ~80MB | 0 | ~1% |
| gopls | ~60MB | 0 | ~1% |
| lua-language-server | ~50MB | 4.5MB | ~1% |
| intelephense | ~40MB | 6.9MB | ~1% |
| Total (all enabled) | ~480MB | ~11MB | ~7% |

Per-Session Overhead

  • Working directory tested: ~/.claude (config files, no source code)
  • Expected LSPs: 0 (no matching extensions)
  • Actual LSPs: 6 (all enabled plugins)
  • Wasted resources: ~480MB RAM + 6 idle processes per session

---

Related Issues

  • #22344 - Subagent system prompt bloat
  • #22345 - Plugin skills lack granular control
  • #13605 - Custom plugin subagents cannot access MCP tools

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗