Skip to content

[Bugs] leaks memory by accumulating copilot.exe worker processes that are never reaped #1543

Description

@charris-msft

Mood: 😊
Category: Bugs

GitHub Copilot app (github.exe) leaks memory by accumulating copilot.exe worker processes that are never reaped

Summary

A single long-running instance of the GitHub Copilot desktop app (github.exe, v1.0.10) spawns copilot.exe worker/session processes (CLI, v1.0.66) and never terminates them, even after the associated session is idle/closed. Over ~4 days a single app instance accumulated 85 copilot.exe processes holding ~17.5 GB of committed (private) memory, ~3.4 GB working set, 26,494 handles, and 2,077 threads. Restarting the app immediately reclaimed almost all of it (down to 8 processes / ~2.2 GB committed).

Version note: the leak was observed on app v1.0.10. Restarting the app updated it to v1.0.11, so the post-restart "healthy" numbers below are from v1.0.11. v1.0.11 has not yet been running long enough to confirm whether the leak is fixed — it should be monitored over several days.

Environment

OS Windows (Windows_NT)
GitHub Copilot app github.exe1.0.10 when leak occurred (now updated to 1.0.11) — C:\Users\<user>\AppData\Local\Programs\GitHub Copilot\github.exe
Copilot CLI worker copilot.exe 1.0.66...\WinGet\Packages\GitHub.Copilot.Prerelease_Microsoft.Winget.Source_8wekyb3d8bbwe\copilot.exe
Usage pattern Multiple long-lived sessions, background agents, scheduled prompts, MCP servers, --yolo

Evidence

Before restart — single app instance, accumulated over 4 days

Aggregate over all copilot.exe processes parented (directly or transitively) by the one github.exe host (PID 60860, running since at least 06-26):

Total copilot.exe processes : 85
Total committed (private)    : 17,583 MB   (~17.5 GB)
Total working set            :  3,377 MB
Total handles                : 26,494
Total threads                :  2,077

Processes by start day — note they are never cleaned up and pile up across days:

Day     Count   PrivMB
06-26     5      1,409
06-27    22      4,661
06-28     5      1,042
06-29    45      8,578
06-30     8      1,892

Process classes (by thread count):

Threads  Count   PrivMB     Role (inferred)
14         37    2,847      helper / worker / MCP child (~75 MB each)
32         44   13,391      session host (~300 MB each)
30/33/43/45 4    ~1,345     active sessions

Parent breakdown of the 85 processes:

34  parented by another copilot.exe   (session host -> worker tree)
31  parented by github.exe (PID 60860, the app)
17  parent already dead (orphaned, still alive & holding memory)
 3  parented by pwsh.exe (interactive terminal sessions)

The vast majority were idle (0–low CPU) but still resident — they were not doing work, just not being reaped.

After restarting the GitHub Copilot app (now on v1.0.11)

github.exe count    : 1   (fresh PID, ~87 MB private)
copilot.exe count   : 8
copilot committed   : 2,170 MB
copilot working set : 1,673 MB
copilot handles     : 3,450

A single restart reclaimed ~15 GB committed and ~80 processes. This confirms the memory was held by accumulated child processes the app failed to terminate, not by legitimate concurrent work.

Orphan behavior

Some copilot.exe processes remained alive after their parent process had exited (17 of the 85 had a dead parent). A few even survived an app restart entirely (e.g. processes launched on 06-26 were still running on 06-30). The app/CLI does not appear to tie a worker's lifetime to its parent, so closing a session/window/terminal leaves the worker resident indefinitely.

Steps to reproduce

  1. Start the GitHub Copilot app and leave it running for multiple days.

  2. Use it normally — open/close sessions, run background agents / scheduled prompts, and use MCP servers and sub-agents.

  3. Periodically observe the process list:

    $c = Get-Process -Name copilot -ErrorAction SilentlyContinue
    "copilot.exe count : {0}" -f $c.Count
    "committed (MB)    : {0:N0}" -f (($c|Measure-Object PrivateMemorySize64 -Sum).Sum/1MB)
    "working set (MB)  : {0:N0}" -f (($c|Measure-Object WorkingSet64 -Sum).Sum/1MB)
    "handles           : {0:N0}" -f (($c|Measure-Object HandleCount -Sum).Sum)
    $c | Group-Object {$_.StartTime.ToString('MM-dd')} | Sort-Object Name |
      Select-Object Name, Count
  4. Observed: the copilot.exe count and total committed memory climb monotonically over days; processes from previous days are still present and idle.

  5. Workaround: restarting the app terminates the children and resets memory.

Expected vs. actual

  • Expected: worker/session copilot.exe processes are terminated when their session/window/agent run completes or is closed; total process count and memory stay roughly proportional to active work.
  • Actual: workers are never reaped; they accumulate across days (85 procs / 17.5 GB observed) until the app is restarted. Some survive even their own parent's exit.

Impact

  • Multi-GB memory growth (17.5 GB committed observed from one app instance) that degrades the whole machine.
  • Handle/thread exhaustion risk (26k handles, 2k threads).
  • Users must manually restart the app to recover.

Hypotheses / suggested investigation

  • Child-process lifetime is not bound to the owning session/window/agent run; on session close the spawned copilot.exe (and its MCP/sub-agent children) are not signaled/killed.
  • No reaping on parent exit (orphans should be terminated, e.g. via job objects on Windows).
  • Background-agent / scheduled-prompt / sub-agent / MCP-server workers may each spawn a copilot.exe that outlives its task.
  • Suggest: attach spawned workers to a Windows Job Object with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE so children die with the host; and explicitly terminate session/agent/MCP child processes on completion or session close.

Useful diagnostic one-liner (process tree + ages)

Get-CimInstance Win32_Process -Filter "Name='copilot.exe'" |
  Select-Object ProcessId, ParentProcessId, CreationDate,
    @{n='Cmd';e={$_.CommandLine}} |
  Sort-Object CreationDate

Field Value
App version 1.0.11
OS Windows 10.0.26200
Theme GitHub
Path /chat
Tenure Week 4

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions