Skip to content

Per-session MCP server and LSP duplication multiplies memory usage across concurrent sessions #13041

Closed

Description

@marcusquinn

Summary

Each OpenCode session spawns its own copies of MCP servers and LSP instances, even when multiple sessions operate on the same project. With 3 concurrent sessions on the same codebase, this results in significant memory duplication that compounds the known unbounded-cache memory growth (#9140, #5363).

Environment

  • opencode version: 1.1.54 (Bun-compiled, darwin-arm64)
  • OS: macOS, Apple Silicon, 64GB RAM
  • Sessions: 3 concurrent TUI sessions on the same project

Observed Behavior

Per-session process duplication

With 3 OpenCode sessions running against the same project, ps shows:

Parent PID Child Process RSS Notes
42568 osgrep mcp 73MB Session 1
42568 bash-language-server 40MB Session 1
43045 osgrep mcp 48MB Session 2
43045 typescript-language-server (x3) 40MB each Session 2 — 3 separate instances
80231 osgrep mcp 557MB Session 3 — same MCP, 7.6x the others

3 separate osgrep mcp processes serving the same index for the same project — ~678MB combined for what could be a single shared daemon.

3 separate typescript-language-server instances spawned by a single session (PID 43045), plus the bash-language-server — ~160MB for LSPs that could share state.

Memory profile of the main processes

PID Uptime RSS %CPU Role
42568 76 min 2.9GB 114% Active session (heavy use)
43045 76 min 700MB 13% Active session
80231 1.5 min 525MB 14% Fresh session

System impact

  • Physical RAM: 63GB used, 288MB free (of 64GB)
  • Compressor: 34GB (macOS compressing half of RAM in-memory)
  • Swap: 1.3GB / 2GB used
  • Load average: 58 / 48 / 51 on a 10-core machine (5-6x oversubscribed)

The memory pressure from duplication forces macOS into heavy compression and swap, which then causes CPU overhead from compress/decompress cycles — a cascading performance degradation.

Proposed Improvements

1. Shared MCP server daemon (high impact)

MCP servers like osgrep maintain an index of the project. Multiple sessions querying the same project should connect to a single shared MCP server process rather than each spawning their own.

Architecture: first session spawns the MCP server and writes a socket/port to a lockfile; subsequent sessions connect to the existing instance. Graceful shutdown when the last session disconnects.

2. Shared LSP server pool (medium impact)

Language servers for the same project/workspace should be shared across sessions, similar to how VS Code shares a single LSP instance across multiple editor tabs.

3. osgrep MCP memory variance

The 3 osgrep mcp instances showed wildly different RSS (73MB, 48MB, 557MB) despite serving the same project. This suggests either a leak within osgrep's MCP mode or inconsistent GC behavior worth investigating.

Related Issues

This issue is distinct from the above: it's about duplication across concurrent sessions, not growth within a single session or orphan cleanup. Fixing the shared-daemon pattern would reduce the baseline memory footprint proportionally to the number of concurrent sessions.

Activity

  1. added
    perfIndicates a performance issue or need for optimization
    on Feb 11, 2026
  2. davidvv commented on Feb 18, 2026

    @davidvv

    Additional Evidence: 61GB VmData Overallocation on Linux

    I'm experiencing the same memory duplication pattern on Linux (11GB RAM, not macOS):

    Environment

    • OS: Linux
    • RAM: 11GB total, 8.7GB used
    • Project: 15,770 files, 622MB disk size
    • Sessions: 2 concurrent on same project

    Process Memory (as of now)

    PID VmRSS VmData Notes
    62194 1.4GB 61GB Started 22:15, 17 threads
    87378 569MB 61GB Started 22:43, 19 threads

    Key Finding: VmData 43× Larger Than VmRSS

    Both processes show extreme overallocation:

    • VmData: 61GB allocated in data segment
    • VmRSS: 1.4GB actual RAM used
    • Ratio: 43:1 (allocated vs used)

    This confirms the duplication pattern, but with additional VmData overallocation on Linux.

    System Impact

    • Total opencode: ~2GB RSS but 122GB VmData allocated
    • Swap: 2.4GB / 4GB used (forced by VmData pressure)
    • Available RAM: Only 3GB remaining

    LRU cache may not be evicting properly for large projects (15,770 files).

  3. marcusquinn commented on Mar 6, 2026

    @marcusquinn
    Author

    Update: the per-session memory multiplication is significantly worse when bash-language-server's hardcoded --external-sources flag triggers unbounded ShellCheck memory growth. Each session spawns its own bash-language-server, each of which spawns its own shellcheck processes that grow to 3-5 GB RSS.

    The upstream root cause fix has been merged: bash-lsp/bash-language-server#1376 adds shellcheckExternalSources: false to omit --external-sources.

    This doesn't solve the architectural issue of per-session LSP duplication, but it eliminates the worst memory offender. Setting SHELLCHECK_EXTERNAL_SOURCES=false before running opencode is an immediate workaround.

  4. thdxr commented on Apr 2, 2026

    @thdxr
    Member

    Closing in favor of #20695 where we're collecting all memory-related problems. Please follow that issue for updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

perfIndicates a performance issue or need for optimization

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions