Skip to content

fix: reduce memory use when indexing Svelte projects - #526

Merged
christoph-sg merged 2 commits into
mainfrom
es/svelte-memory
Nov 3, 2026
Merged

christoph-sg merged 2 commits into
mainfrom
es/svelte-memory

Conversation

@eseliger

@eseliger eseliger commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Some improvements found when investigating memory usage of indexing Sourcegraph's monorepo.

About 600 MB comes from two things the Svelte support keeps around without needing to:

  • Decoded source maps. svelte2tsx emits high-resolution maps, with a segment for most generated characters. SvelteSourceInfo decoded every map when the program was created and kept all of them until the project finished. In client/web-sveltekit, with 1,153 components, that was 5.3M segments, about 540 MB. Each SvelteSourceInfo now keeps only the encoded map and builds the TraceMap on first lookup. The new SourceInfo.releaseCaches() drops it after the constructor has collected its ranges and again after the file's document is written, so only the file being indexed holds a decoded map.
  • Uncached package.json lookups. Svelte projects override resolveModuleNameLiterals without getModuleResolutionCache, so createProgram has no package.json cache. Every source file rereads the nearest package.json and keeps its own parsed copy in packageJsonScope. The host now returns the cache SvelteSupport already uses, and 4,669 files share 351 copies instead of keeping 4,669, which saves about 60 MB.

Test plan

Existing unit and snapshot tests pass unchanged; the Svelte snapshots exercise rebuilding the trace map after it has been released.

Measured on sourcegraph/sourcegraph, comparing builds of main and this branch:

main (0.6.0) This branch
Live heap after indexing client/web-sveltekit (after GC) 4,326 MB 3,724 MB
Smallest --max-old-space-size for index --pnpm-workspaces 4,097–4,608 MB 3,585–3,840 MB
index.scip byte-identical to main, for both the single project and the whole workspace

Svelte projects override resolveModuleNameLiterals without providing
getModuleResolutionCache, so createProgram has no package.json cache.
Each source file then rereads the nearest package.json and keeps its
own parsed copy in packageJsonScope.

Return the cache SvelteSupport already uses for module resolution.
In Sourcegraph's client/web-sveltekit, 4,669 files shared 351
package.json objects instead of keeping 4,669 copies, and the live
heap fell by about 60 MB. The index is byte-identical.

Amp-Thread-ID: https://ampcode.com/threads/T-01a19cd4-1b61-72cc-ae15-02a5c02c5846
svelte2tsx emits high-resolution source maps, with a segment for most
generated characters. SvelteSourceInfo decoded each map when the program
was created and kept every decoded map until the project finished. In
Sourcegraph's client/web-sveltekit (1,153 components), that kept 5.3M
segments, about 540 MB, on the heap at once.

Keep only the encoded map on each SvelteSourceInfo and build the
TraceMap on first lookup. A new SourceInfo.releaseCaches drops the
decoded map after the constructor has collected its ranges and after
the file's document is indexed. Each map is decoded at most twice, which
costs little compared to holding all of them.

Amp-Thread-ID: https://ampcode.com/threads/T-01a19cd4-1b61-72cc-ae15-02a5c02c5846
@eseliger
eseliger marked this pull request as ready for review November 2, 2026 22:43
@eseliger
eseliger requested a review from christoph-sg November 2, 2026 22:43
@christoph-sg
christoph-sg merged commit e952144 into main Nov 3, 2026
5 checks passed
@christoph-sg
christoph-sg deleted the es/svelte-memory branch November 3, 2026 08:44
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.

2 participants