Tag: Performance Optimization

  • Fixing High CPU Spikes and Freezes During Large Codebase Indexing in Cursor

    Fixing High CPU Spikes and Freezes During Large Codebase Indexing in Cursor

    TL;DR

    • High CPU spikes during Cursor codebase indexing are usually not an embedding-generation cost — they mostly come from background rg (ripgrep) processes scanning large binary/artifact-heavy workspaces with wide-scope flags.
    • Developers can shrink that scan scope by excluding heavy files with .cursorignore, .cursorindexingignore, and a global ignore list, disabling symlink traversal, and keeping the indexed file count low — all of which narrow what the background scan has to cover.
    • Separately, adding watcher exclusions, capping TypeScript server memory, and disabling redundant linting extensions address other CPU-consuming processes that often run alongside indexing, not the scan itself.

    Understanding Why Cursor Indexing Triggers High CPU Spikes

    Cursor builds a searchable semantic index of a project’s codebase by generating Vector Embeddings for code files. This Codebase Indexing process powers AI features such as Semantic Search, @Codebase context retrieval, and agent reasoning across entire repositories. (Cursor Tab is a separate feature that draws on recent edits, surrounding code, and linter errors rather than the codebase index — though .cursorignore still blocks Tab suggestions on excluded files.) However, when opening large codebases, monorepos, or projects containing heavy build artifacts, third-party packages, binary models, or deeply nested dependencies, indexing can cause temporary CPU spikes, increased memory usage, or responsiveness freezes.

    The spikes are not primarily an embedding-generation cost. According to a Cursor forum thread where Cursor support diagnosed a user’s report of CPU usage staying above 350% across multiple processes, the runaway cost comes from background rg (ripgrep) processes that scan the workspace for rules files and codebase indexing. On workspaces with many large binary files and artifacts, flags like --hidden, --follow, and --no-ignore-parent dramatically expand the scan scope, and it is this filesystem scan — not the downstream embedding step — that pins the CPU. (The same thread also documents a separate, unresolved bug where tracked files appear to vanish after a crash during heavy indexing over Remote SSH; support notes ripgrep itself is read-only and cannot delete files, so the cause there remains an open question distinct from the CPU spikes discussed here.)

    To control indexing behavior and avoid background performance degradation, Cursor exposes several configuration mechanisms:

    • .cursorignore: Placed in the project root directory, this file uses standard .gitignore pattern syntax to explicitly exclude files and directories from all AI context operations and indexing. Its scope includes blocking files from Semantic Search indexing, Cursor Tab, inline editing, Agent tools, and @ mentions.
    • .cursorindexingignore: A specialized configuration file used exclusively to skip specified files or folders during background Codebase Indexing. Unlike .cursorignore, developers can still manually reference items listed in .cursorindexingignore using @ mentions when necessary.
    • .gitignore and Default Ignore Integration: Cursor automatically respects standard .gitignore rules across subdirectories, along with a built-in default ignore list (e.g., lockfiles, build artifacts, and binary or media files) for Codebase Indexing.
    • A global ignore list: Cursor’s settings expose a way to apply exclusion patterns (e.g., **/.env, **/dist/**) across all open workspaces without committing workspace-specific ignore files — look under the Indexing/Ignore Files section of Cursor Settings, since the exact menu path has moved between versions.
    • Indexing & Docs Settings Panel: Accessible via Cursor Settings > Features > Codebase Indexing (or Indexing & Docs), this panel displays workspace indexing status, permits inspection of included files through “View included files”, provides toggles for automatic indexing on new repositories, and offers controls to clear cache or trigger manual re-indexing.

    To prevent performance issues and mitigate CPU spikes and freezes in large environments, community guides and support threads recommend several practices:

    • Exclude Heavy and Non-Code Artifacts: Place large dependency folders (node_modules/, vendor/), generated outputs (dist/, build/), machine learning checkpoints (.pth, .onnx, .npz), and log files into .cursorignore — this is what keeps the rg scan scope small in the first place.
    • Keep the Indexed File Count in the 500–2,000 Range: eastondev.com’s guide frames this range as its primary recommendation for query speed rather than CPU load directly, and pairs it with at least 16GB of RAM (32GB for comfortable headroom) — but a smaller indexed working set is also, by definition, less for the background rg scan above to cover.
    • Disable Symlink Traversal: Set search.followSymlinks to false in settings to prevent background file search tools from recursively traversing symlink loops in complex workspaces.
    • Configure File Watcher Exclusions: Add heavy generated directories to files.watcherExclude in workspace settings (.vscode/settings.json) to minimize OS file-system watching overhead.
    • Cap TypeScript Server Memory and Disable Redundant Linters (a separate CPU source, not the indexing rg scan above): smartremotegigs.com recommends setting typescript.tsserver.maxTsServerMemory to a fixed value (e.g., 2048) and disabling real-time linting extensions (ESLint, SonarLint, Prettier), since these run as their own processes alongside indexing and can compound the same symptoms — CPU spikes and freezes — through an entirely different mechanism.
    • Scoped Monorepo Strategies: For large monorepos, structure project rules (.cursor/rules/*.mdc) or set up localized .cursorignore rules to restrict the focus of AI scanning to relevant sub-projects.
    • Last Resort — Clear the Index Cache: If spikes persist after the above, delete Cursor’s local index cache (~/Library/Application Support/Cursor/Index/ on Mac, %APPDATA%\Cursor\Index\ on Windows) and let it reindex from scratch.

    Sources: towardsdatascience.com, eastondev.com, cursor.com, smartremotegigs.com

    Closing thoughts

    When examining these performance dynamics and configuration controls, severe CPU spikes during indexing are rarely a flaw in Cursor itself, but rather the cost of letting background rg scans run unconstrained across massive, artifact-heavy codebases. Developers do not need to sacrifice deep AI features to maintain a fluid workspace; the solution lies in thoughtfully defining scanning boundaries using targeted options like .cursorindexingignore and a global ignore list, and in keeping the indexed file count low. By pairing these ignore configurations with precise editor tweaks — disabling symlink traversal, turning off file watchers for generated directories, and separately taming TypeScript server memory or redundant linting extensions — you eliminate performance bottlenecks without losing context retrieval. Ultimately, taking a proactive approach to workspace boundaries turns background indexing from a resource-draining nuisance into a quiet, highly responsive feature.

    Frequently Asked Questions

    Why does codebase indexing in Cursor trigger high CPU spikes?

    Cursor generates vector embeddings for code files to build a searchable semantic index, but the CPU spikes themselves mostly trace back to an earlier step: background rg (ripgrep) processes scanning the workspace for rules files and codebase indexing. On workspaces with many large binary files, build artifacts, or deeply nested dependencies, wide-scope scan flags can push CPU usage past 350% before embedding generation even begins.

    What is the difference between .cursorignore and .cursorindexingignore?

    .cursorignore excludes files from all AI context operations and indexing, blocking them from @ mentions, inline editing, and Agent tools. Conversely, .cursorindexingignore only skips files during background codebase indexing, allowing developers to still manually reference them using @ mentions.

    How can developers exclude files globally across all workspaces in Cursor?

    Cursor’s settings expose a global ignore list under the Indexing/Ignore Files section (the exact menu path has moved across versions) that applies universal exclusion patterns across all open workspaces without requiring workspace-specific ignore files.

    What settings adjustments can minimize performance bottlenecks during indexing?

    Developers can set search.followSymlinks to false to prevent recursive symlink loops and add heavy generated directories to files.watcherExclude in workspace settings to reduce OS file-system watching overhead.