Pylance runs as a language server inside VS Code and can consume significant CPU and memory on large projects. This guide covers the key settings for controlling resource usage and the trade-offs each option involves.
- Language Server Mode
- Diagnostic Mode
- Indexing Controls
- Exclude Patterns
- Extra Path Cost
- Node.js Heap Limit
- Per-Folder Memory in Multi-Root Workspaces
- Performance Presets
- FAQ
python.analysis.languageServerMode is the single most impactful performance setting. It sets defaults for several other settings at once:
| Setting | "light" Default |
"default" Default |
"full" Default |
|---|---|---|---|
exclude |
["**"] |
[] |
[] |
indexing |
false |
true |
true |
typeCheckingMode |
"off" |
"off" |
(unchanged) |
useLibraryCodeForTypes |
false |
true |
true |
autoImportCompletions |
(unchanged) | false |
true |
userFileIndexingLimit |
(unchanged) | 2000 |
-1 (unlimited) |
You can override any individual setting even when a mode is active — the mode only sets defaults, it doesn't lock them.
Example: Enable indexing in light mode:
{
"python.analysis.languageServerMode": "light",
"python.analysis.indexing": true
}python.analysis.diagnosticMode controls which files Pylance actively analyzes for errors:
"openFilesOnly"(default): Only files open in the editor are analyzed. The most memory-efficient option."workspace": All Python files in the workspace are analyzed. Provides project-wide diagnostics but uses more memory and CPU.
For large projects, "openFilesOnly" is strongly recommended. Switch to "workspace" only if you need to see all errors across the project without opening each file.
Indexing pre-parses workspace files and library packages to enable fast auto-imports, workspace symbol search (Ctrl+T), and completions. The trade-off is upfront CPU and memory usage.
| Setting | Effect |
|---|---|
python.analysis.indexing |
true (default) enables background indexing; false disables it |
python.analysis.userFileIndexingLimit |
Maximum number of user files to index (default: 2000; -1 for unlimited) |
python.analysis.packageIndexDepths |
Controls how deep Pylance indexes specific third-party packages |
python.analysis.includeVenvInWorkspaceSymbols |
Include venv site-packages symbols in workspace symbol search (default: false) |
python.analysis.includeExtraPathSymbolsInSymbolSearch |
Include extraPaths symbols in workspace symbol search (default: false) |
Disable indexing ("python.analysis.indexing": false) if:
- Startup is too slow and you can tolerate reduced auto-import coverage
- You mainly work in open files and don't rely on workspace symbol search
- Memory usage is a concern on constrained machines
Without indexing, auto-imports still work for open files, their transitive imports, and stdlib — but won't find symbols in files that haven't been loaded.
python.analysis.exclude removes directories from Pylance's file discovery. This is one of the most effective ways to reduce memory and indexing time.
Common patterns to exclude:
{
"python.analysis.exclude": ["**/node_modules", "**/.git", "**/build", "**/dist", "**/data", "**/__pycache__"]
}In multi-root workspaces, you can also exclude entire workspace folders you're not actively working on:
{
"python.analysis.exclude": ["${workspaceFolder:unused-folder}"]
}Note: The built-in defaults (
**/node_modules,**/__pycache__, dotfiles, and auto-detected virtual environments like.venv/venv) are excluded by default, and yourexcludeentries are added on top of them. You don't need to re-list the defaults to keep them excluded. To turn the built-in defaults off, setpython.analysis.useDefaultExcludestofalse.
Note: If
pyrightconfig.jsonorpyproject.tomlwith[tool.pyright]exists, the VS Codeexcludesetting is ignored — setexcludein the config file instead. See How to Troubleshoot Pylance Settings.
Every directory in extraPaths becomes an import search root and a file-watch root. Each unresolved import is probed against every extra path in order, and each root is watched for changes, so a large extraPaths list adds both lookup time and memory.
This matters most when an entry uses a glob pattern: a broad glob can expand to hundreds of directories. Keep the cost down by:
- Scoping globs narrowly: anchor to a fixed prefix (
external/rules_python~~pip~pip_310_*/site-packages) instead of a greedy**/site-packages. - Using execution environments: put per-subtree paths in
executionEnvironmentsso each file only carries the roots relevant to its subtree. - Limiting symbol-search scope:
includeExtraPathSymbolsInSymbolSearchmakes workspace symbol search scan expanded extra-path directories too; leave it off unless you need it. - Reducing watching: if a generated dependency tree doesn't change during a session, exclude it from file watching (e.g.
files.watcherExclude) — imports still resolve, you just stop watching those roots.
Glob expansion itself happens once when configuration loads, not per import. See How to Use Glob Patterns in Extra Paths with Pylance for the full behavior and more mitigations.
By default, Pylance runs inside VS Code's built-in Node.js runtime, which uses pointer compression. This limits the effective heap to approximately 4 GB, regardless of system RAM.
When languageServerMode is "full" (or python.analysis.nodeExecutable is set), Pylance launches in a separate Node.js process where the --max-old-space-size=8192 argument takes effect, raising the limit to 8 GB.
If you hit "JavaScript heap out of memory" errors or "Extension host terminated unexpectedly," switch to an external Node.js runtime and optionally increase the heap:
-
Set
python.analysis.nodeExecutableto"auto"(downloads a standalone Node.js) or setlanguageServerModeto"full"(which does this automatically):{ "python.analysis.nodeExecutable": "auto" } -
Optionally increase
python.analysis.nodeArgumentsbeyond the 8 GB default:{ "python.analysis.nodeArguments": ["--max-old-space-size=16384"] } -
Restart VS Code (both settings require a full restart).
These apply only when running with an external Node.js (nodeExecutable or languageServerMode: "full"):
| Project Size | Recommended --max-old-space-size |
|---|---|
| Small–Medium (< 5,000 files) | 8192 (default with external Node) |
| Large (5,000–20,000 files) | 12288–16384 |
| Very large (> 20,000 files) | 16384–32768 |
Tip: Increasing heap doesn't fix the root cause — it gives Pylance more room to work. Prefer reducing Pylance's workload first (fewer workspace folders,
"openFilesOnly", properexcludepatterns, disable indexing).
See the python.analysis.nodeExecutable and python.analysis.nodeArguments setting pages for details and scope considerations.
In multi-root workspaces, each workspace folder creates a separate analyzer service. With many folders (>10–20), the combined memory usage can exceed the Node.js heap limit.
- Open Output → Pylance and look for per-folder startup/analysis messages
- Check how many workspace folders are configured in your
.code-workspacefile - Look for "JavaScript heap out of memory" or "Extension host terminated unexpectedly" in the Output panel
| Strategy | Effect |
|---|---|
Switch to executionEnvironments |
Single analyzer instead of per-folder — dramatically reduces memory |
Use useNearestConfiguration |
Single workspace with auto-discovered configs — lower overhead than multi-root |
Set languageServerMode to "light" |
Minimizes per-folder memory footprint |
Use "openFilesOnly" diagnostic mode |
Avoids analyzing all files in every folder |
| Exclude unused folders | "python.analysis.exclude": ["${workspaceFolder:unused-folder}"] |
| Increase the heap limit | See Node.js Heap Limit above |
{
"python.analysis.languageServerMode": "light",
"python.analysis.diagnosticMode": "openFilesOnly",
"python.analysis.indexing": false
}{
"python.analysis.diagnosticMode": "openFilesOnly",
"python.analysis.userFileIndexingLimit": 1000,
"python.analysis.indexing": true
}{
"python.analysis.languageServerMode": "full",
"python.analysis.diagnosticMode": "workspace"
}Each workspace folder creates a separate analyzer service. With many folders (>10–20), the combined memory usage can exceed the Node.js heap limit. Mitigations:
- Use
languageServerMode: "light"to minimize per-folder memory - Exclude folders you're not working on
- Switch to
executionEnvironmentsinstead (single analyzer) - Use
useNearestConfigurationinstead (single workspace)
No. Auto-import completions are driven by the indexer, not by diagnostic mode. You can use "openFilesOnly" and still get full auto-import coverage if indexing is enabled.
Yes. Override the default:
{
"python.analysis.languageServerMode": "light",
"python.analysis.indexing": true
}But also set exclude to a narrower pattern — light mode defaults exclude to ["**"], which limits indexing to open files.
Look for these signs in the Output → Pylance panel or VS Code notifications:
- "Extension host terminated unexpectedly"
- "JavaScript heap out of memory"
- Pylance stops responding (no hovers, completions, or diagnostics)
- Very slow startup or analysis
- How to Use Glob Patterns in Extra Paths with Pylance — deterministic wildcard expansion and its cost
- How to Fix Unresolved Import Errors in Pylance — import resolution and common missing-import fixes
- How to Troubleshoot Pylance Settings — config file precedence and setting interactions
- How to Set Up a Python Monorepo with Pylance — multi-root workspaces and execution environments
For more information on Pylance settings and customization, refer to the Pylance Settings and Customization documentation.
This document was generated with the assistance of AI and has been reviewed by humans for accuracy and completeness.