Skip to content

fix(oxfmt): destroy existing Tinypool before re-initialising in LSP mode#24183

Closed
tsushanth wants to merge 1 commit into
oxc-project:mainfrom
tsushanth:fix/24147-tinypool-worker-leak
Closed

fix(oxfmt): destroy existing Tinypool before re-initialising in LSP mode#24183
tsushanth wants to merge 1 commit into
oxc-project:mainfrom
tsushanth:fix/24147-tinypool-worker-leak

Conversation

@tsushanth

Copy link
Copy Markdown

Problem

initExternalFormatter() creates a new Tinypool instance each time it is called. In --lsp mode the process stays alive indefinitely, and the Rust side calls initExternalFormatter() again on config reload or project switch. The old pool and its child_process workers are never destroyed, so they accumulate.

Observed in production: 1,500+ orphaned node tinypool/.../process.js processes, 30+ GB RAM after several hours of normal LSP usage.

Fix

Add the same guard that disposeExternalFormatter() already applies on CLI exit — if a pool exists, destroy it before constructing the new one:

export async function initExternalFormatter(numThreads: number): Promise<void> {
  if (pool !== null) {
    await pool.destroy();
    pool = null;
  }
  pool = new Tinypool({ ... });
}

Fixes #24147

initExternalFormatter() was called multiple times during a long-lived LSP
session (e.g. on config reload or project switch) without destroying the
previous Tinypool instance. The orphaned child_process workers accumulate
indefinitely, reaching 1000+ processes and 30+ GB RAM after hours of use.

Guard the function: if a pool already exists, destroy it before creating
the new one. disposeExternalFormatter() already does this on CLI exit;
this applies the same pattern to the init path.

Fixes oxc-project#24147
@leaysgur

leaysgur commented Jul 6, 2026

Copy link
Copy Markdown
Member

Thank you.

I'll take it over in #24197. I felt it would be better to keep it as it is rather than re-init it every time.

@leaysgur leaysgur closed this Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-formatter Area - Formatter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

oxfmt/lsp: tinypool child_process workers accumulate indefinitely (~1500+ processes, 30+ GB RAM)

4 participants