Skip to content

fix(vscode): lower tsserver heap ceiling, pin more UI-only extensions - #789

Open
ppat wants to merge 1 commit into
mainfrom
vscode-remote-heap-caps
Open

fix(vscode): lower tsserver heap ceiling, pin more UI-only extensions#789
ppat wants to merge 1 commit into
mainfrom
vscode-remote-heap-caps

Conversation

@ppat

@ppat ppat commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Summary

Follow-up to #773 / #772, in response to a coordinated change in ppat/coder
that apportions the workspace memory watchdog's per-role budgets against a
2048 MiB envelope for the whole remote VS Code tree. The watchdog kills on a
ten-minute dwell; this is the "shrink it at the source instead" half of that
work, entirely in dotfiles.

  • typescript.tsserver.maxTsServerMemory -> js/ts.tsserver.maxMemory,
    2048 -> 768.
    The old key is deprecated (still honored as a fallback,
    verified in the installed extension's compiled JS) and the old value was
    wrong for the actual topology: TypeScript spawns two tsserver processes
    that each read this same setting independently, so 2048 let tsserver alone
    claim up to 4096 MiB against a 2048 MiB budget. 768 sits well above both
    processes' measured resting PSS on a live workspace (~142 / ~112 MiB).
  • remote.extensionKind: added hashicorp.hcl and samuelcolvin.jinjahtml
    alongside the existing vscode-icons-team.vscode-icons /
    bierner.markdown-mermaid entries. Both are grammar/syntax-highlighting
    only -- no LSP client, no fs/child_process use -- confirmed against the
    extensions actually installed under ~/.vscode-server/extensions on a live
    workspace. davidanson.vscode-markdownlint was considered and left on the
    remote (default): it contributes a markdownlint.lintWorkspace command
    that does real work against the workspace filesystem.

Both changes land in the Mac client User settings file only. Verified
js/ts.tsserver.maxMemory and the deprecated key are both scope: "window"
in the installed extension's own configuration.json, and remote.extensionKind
is APPLICATION-scoped per VS Code's remote docs (as #773 already established) --
neither belongs in the remote Machine settings file, which parses only
[MACHINE, MACHINE_OVERRIDABLE] and would silently drop them. No changes to
the Machine settings file in this PR.

Coverage gap (cannot verify from here)

Written from inside the live Coder workspace this targets, where chezmoi apply is off-limits (shared pod, live sessions) and private_Library/** is
ignored entirely on this host (.chezmoiignore, homeDir == /home/coder) --
so chezmoi diff cannot exercise this file from here either. Verified
instead with chezmoi execute-template (fake bitwardenSecrets substitution,
same technique full-apply-test.yaml uses) confirming the template renders
to valid JSONC, plus direct inspection of the running server's processes and
the installed extensions' source/package.json on that same live workspace.

What the operator should check after chezmoi apply on the Mac and a
window reload/reconnect:
open Settings UI in the reconnected remote window,
search tsserver.maxMemory, confirm it shows 768 with User (not a
default/Remote-Machine) provenance badge; same for the two new
remote.extensionKind entries, then confirm via Help: Show Running
Extensions
that hashicorp.hcl and samuelcolvin.jinjahtml show as
running on the UI extension host rather than the remote one. Also worth
noting: the previous typescript.tsserver.maxTsServerMemory: 2048 from
#773 does not appear to have taken effect yet on this same live workspace --
its running tsserver processes still show the extension's own unconfigured
default (--max-old-space-size=3072), on a server session that started
after #773 merged. Most likely explanation is simply that chezmoi apply
hasn't run on the Mac since #773, but I can't rule out a scope-routing issue
from here -- the check above will settle it either way for this PR's value
too.

What's still uncapped, and why nothing was added for it

Only js/ts.tsserver.maxMemory and remote.extensionKind are usable levers
from dotfiles. Checked each other node-backed process in the tree
(/proc/<pid>/cmdline on a live workspace) for an equivalent heap-ceiling
setting and found none: the extension host itself (685-738 MiB PSS observed,
the tree's biggest and most volatile process, and the reason
remote.extensionKind matters more than the heap ceiling here), the file
watcher, pty host, and the JSON/Markdown/TOML language server processes all
have no exposed memory-limit configuration. NODE_OPTIONS would reach all of
them (none pass an explicit --max-old-space-size of their own, so an
inherited env var would apply) but only if set in whatever environment
launches the remote server process tree -- which on a Coder workspace is
provisioned by the template, not dotfiles, and setting it globally via a
dotfiles shell-profile export would leak the same low ceiling onto every
unrelated Node process the operator or Claude Code runs in a terminal. Not
implemented for that reason. This means the PR does not by itself guarantee
the whole tree fits 2048 MiB -- see the comment above js/ts.tsserver.maxMemory.

Test plan

  • pre-commit run --all-files clean (baseline was already clean at
    origin/main, no unrelated findings touched)
  • chezmoi execute-template on the changed file (fake bitwardenSecrets
    substitution) renders valid JSONC
  • Operator: chezmoi apply on the Mac, reload/reconnect the remote
    window, verify per the Settings UI / Running Extensions checks above

Ref: #772

🤖 Generated with Claude Code

https://claude.ai/code/session_0197hA8JPwGMX8wufiQiy6oz

typescript.tsserver.maxTsServerMemory (dotfiles#773) is a deprecated key --
still honored as a fallback in the installed extension (verified against its
compiled dist/extension.js) but replaced here with the current
js/ts.tsserver.maxMemory, same window scope. Its value was also wrong for
the goal: TypeScript spawns two tsserver processes that each read this same
setting independently, so the previous 2048 let tsserver alone claim up to
4096 MiB against the operator's 2048 MiB budget for the whole remote VS Code
tree. 768 sits well above both processes' measured resting PSS on a live
workspace (~142/~112 MiB) while actually bounding the pair.

Adds hashicorp.hcl and samuelcolvin.jinjahtml to remote.extensionKind
alongside the existing vscode-icons/markdown-mermaid entries -- both are
grammar-only (no LSP client, no fs/child_process use in their source),
confirmed against the extensions actually installed under
~/.vscode-server/extensions on a live workspace. davidanson.vscode-markdownlint
was considered and left on the remote: its markdownlint.lintWorkspace command
does real work against the workspace filesystem.

Most of the tree still has no heap-ceiling knob at all (extension host,
file watcher, pty host, the JSON/Markdown/TOML language servers), so this
does not by itself guarantee the tree fits 2048 MiB -- see the comment above
js/ts.tsserver.maxMemory and dotfiles#772.

Ref: #772

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant