Skip to content

Latest commit

 

History

History
275 lines (184 loc) · 15.2 KB

File metadata and controls

275 lines (184 loc) · 15.2 KB

How to Tune Pylance Performance

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.


Table of Contents


Language Server Mode

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
}

Diagnostic Mode

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 Controls

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.

Key Settings

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)

When to Disable Indexing

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.


Exclude Patterns

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 your exclude entries 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, set python.analysis.useDefaultExcludes to false.

Note: If pyrightconfig.json or pyproject.toml with [tool.pyright] exists, the VS Code exclude setting is ignored — set exclude in the config file instead. See How to Troubleshoot Pylance Settings.


Extra Path Cost

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 executionEnvironments so each file only carries the roots relevant to its subtree.
  • Limiting symbol-search scope: includeExtraPathSymbolsInSymbolSearch makes 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.


Node.js Heap Limit

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:

  1. Set python.analysis.nodeExecutable to "auto" (downloads a standalone Node.js) or set languageServerMode to "full" (which does this automatically):

    {
        "python.analysis.nodeExecutable": "auto"
    }
  2. Optionally increase python.analysis.nodeArguments beyond the 8 GB default:

    {
        "python.analysis.nodeArguments": ["--max-old-space-size=16384"]
    }
  3. Restart VS Code (both settings require a full restart).

Recommended Heap Sizes

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", proper exclude patterns, disable indexing).

See the python.analysis.nodeExecutable and python.analysis.nodeArguments setting pages for details and scope considerations.


Per-Folder Memory in Multi-Root Workspaces

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.

Diagnosis

  1. Open Output → Pylance and look for per-folder startup/analysis messages
  2. Check how many workspace folders are configured in your .code-workspace file
  3. Look for "JavaScript heap out of memory" or "Extension host terminated unexpectedly" in the Output panel

Mitigations

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

Performance Presets

Large Projects (minimal resource usage)

{
    "python.analysis.languageServerMode": "light",
    "python.analysis.diagnosticMode": "openFilesOnly",
    "python.analysis.indexing": false
}

Medium Projects (balanced)

{
    "python.analysis.diagnosticMode": "openFilesOnly",
    "python.analysis.userFileIndexingLimit": 1000,
    "python.analysis.indexing": true
}

Small Projects (full features)

{
    "python.analysis.languageServerMode": "full",
    "python.analysis.diagnosticMode": "workspace"
}

FAQ

Q: Why does Pylance crash with many workspace folders?

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:

  1. Use languageServerMode: "light" to minimize per-folder memory
  2. Exclude folders you're not working on
  3. Switch to executionEnvironments instead (single analyzer)
  4. Use useNearestConfiguration instead (single workspace)

Q: Does diagnosticMode: "workspace" affect auto-imports?

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.

Q: Can I enable indexing in light mode?

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.

Q: How do I know if Pylance is running out of memory?

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

Related Guides


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.