Cursor Slow on a Large Codebase? Fix It in This Order
The short answer: on a large repository, Cursor slowness is almost always one of five things, and they are worth checking in this order. The index is
NexaSphere Team
Author

The short answer: on a large repository, Cursor slowness is almost always one of five things, and they are worth checking in this order. The index is covering files it should never see. File watchers are watching a directory tree that is far larger than your source. A language server (usually TypeScript or Python) is doing whole-workspace analysis. An extension is blocking the extension host. Or the chat thread has grown so long that every message ships a small book to the model. Fix them one at a time and measure in between, because if you change six settings at once you will never know which one mattered.
Cursor is a fork of VS Code, so most of the editor-side performance tooling you already know still applies, and most of the AI-side tuning is Cursor specific. That split is the useful mental model.
Step one: figure out which "slow" you have
"Cursor is slow" describes at least three different problems with three different fixes.
Typing lag. Characters appear late, autocomplete stutters, saving hangs. This is editor side. Look at watchers, language servers, and extensions.
AI responses are slow or wrong. The editor feels fine but chat takes a long time to start streaming, or it answers using the wrong files. This is context and indexing.
The whole app is sluggish and the fans are loud. This is resource exhaustion. Memory or CPU, and often not Cursor's fault alone.
Open the process explorer from the Help menu. You get a per-process breakdown of CPU and memory: the main window, the extension host, the file watcher, and each language server as a separate row. Sit with it for thirty seconds while you reproduce the slowness. Whatever is pinned at high CPU is your suspect, and you have now replaced guessing with evidence. The command palette also has a startup performance view if the problem is that opening the project takes minutes.
Step two: shrink what gets indexed
Cursor builds an index of your repository so that the AI can retrieve relevant code. On a big monorepo, the default scope is usually much wider than what you actually want the model to read.
Two files control this:
.cursorignorekeeps files out of AI features entirely..cursorindexingignorekeeps files out of the index while leaving them reachable if you reference them directly.
Use the second one for the large majority of cases. You do not want the model retrieving from these, but you occasionally want to open one and ask about it.
Good candidates, in roughly the order they cause pain:
dist/
build/
.next/
out/
coverage/
**/*.min.js
**/*.map
**/__snapshots__/
**/generated/
**/*.pb.go
vendor/
fixtures/
*.lock
Generated code is the big one. A protobuf output directory or a generated API client can be larger than your handwritten source, and it is nearly useless as retrieval context because it teaches the model your generator's style instead of yours. Test snapshots are the same problem with more noise.
After editing these files, trigger a resync from the indexing section of Cursor's settings. Also keep in mind that switching between distant branches invalidates a lot of the index, so a slow patch right after a big rebase is expected rather than broken.
Step three: stop watching the whole tree
This is the fix people skip, and on monorepos it is frequently the largest single win. The editor maintains OS-level watchers on your workspace. Every build output directory it watches is a stream of change events during every build, and each event costs the renderer, the extension host, and Git decorations some work.
Three settings do three different jobs, and confusing them is common:
files.watcherExcludestops the OS watcher. This is the performance one.search.excluderemoves paths from full-text search results.files.excludehides paths from the file explorer.
Put your build directories in all three, but understand that only the first changes CPU behavior. Configure it in .vscode/settings.json inside the repo so your teammates get the benefit too:
{
"files.watcherExclude": {
"**/node_modules/**": true,
"**/dist/**": true,
"**/.next/**": true,
"**/target/**": true,
"**/.venv/**": true,
"**/coverage/**": true
}
}
If your repository has tens of thousands of files under version control, also try turning off Git auto-refresh and file decorations temporarily. If the sluggishness disappears, you have found your culprit and can decide what to trade.
Step four: give the language server less to do
The TypeScript server is the usual offender in a JavaScript or TypeScript monorepo. Two things help.
First, memory. The TS server runs with a default heap ceiling, and on a large project it will spend its life garbage collecting right below that ceiling. Raising typescript.tsserver.maxTsServerMemory to a value your machine can actually spare (a few thousand megabytes on a 32 GB laptop) often removes a specific kind of periodic freeze. Verify it in the process explorer rather than assuming.
Second, scope. If your monorepo has one enormous tsconfig.json covering every package, the server loads every package for every keystroke. Project references split that into units that can be loaded and rebuilt independently. That is a real refactor, not a settings toggle, but on a repo you will work in for years it pays for itself.
For Python, the equivalent lever is analysis scope. Setting the language server to analyze open files rather than the entire workspace changes CPU use dramatically, at the cost of losing some cross-file diagnostics you did not open. For Rust, restricting the cargo check target and disabling proc-macro expansion for the heaviest crates has a similar effect.
When something feels stuck rather than slow, restart the specific server from the command palette before restarting the whole editor. It is faster and it tells you which server was wedged.
Step five: bisect your extensions
You have probably accumulated extensions over years. Any single one can block the extension host, and when the extension host blocks, everything that depends on it stalls at once.
Start extension bisect from the Help menu. It disables half your extensions, asks whether the problem is still there, and repeats. Five or six answers later you have the offender by name. This takes a few minutes and beats an hour of theorizing.
A useful habit afterward: disable heavyweight extensions per workspace rather than globally. A Docker or database extension you need in one project does not need to run in the other twelve.
Step six: keep the AI context deliberate
Everything above is about the editor. This part is about why answers get slow and worse over a long session.
Long chat threads are expensive on every turn, because the whole conversation goes along for the ride. When a thread stops being about the task you are actually doing, start a new one. It is not just cheaper, it is more accurate, because stale context competes with current context.
Point at files explicitly instead of asking the model to go find them. Referencing three specific files gives the model a smaller, better-chosen set of code than a vague question that triggers a broad retrieval sweep. On a big repo, retrieval quality is the thing that decides whether the answer is good, and you know your codebase better than the retriever does.
Put durable project conventions in Cursor's rules files rather than repeating them in every prompt. And match the model to the task. The strongest reasoning models are slower by design, and a lot of day to day edits do not need them.
Step seven: open a smaller workspace
If you work in one package of a monorepo all day, open that package as the workspace instead of the repository root. Index, watchers, search, and language server scope all shrink at once. When you need cross-package visibility, add the second package as a multi-root folder rather than opening everything.
This feels like a workaround. It is the single most effective change most people make.
When it is the machine, not the editor
A few environment level causes that look exactly like editor bugs:
- Antivirus scanning your source tree. On Windows, adding your repository and the editor to the real-time scanning exclusions is a well known and large improvement.
- Files on a network drive or synced folder. Cloud sync tools fight with file watchers. Keep repositories on local disk.
- Cross-filesystem access under WSL. Working on files stored on the Windows side from inside a Linux environment is slow at the filesystem layer, and no editor setting fixes it. Move the repository into the Linux filesystem.
- Memory pressure. An Electron editor, a language server, a dev server, a test watcher, and a browser will exhaust 16 GB. Watch actual memory during a slow moment before buying anything.
A fifteen minute triage sequence
- Reproduce the slowness with the process explorer open. Note the top process.
- Add build and generated directories to
files.watcherExclude. Reload the window. - Add the same paths to
.cursorindexingignoreand resync the index. - Restart the language server. If that helps, raise its memory ceiling or narrow its scope.
- Run extension bisect.
- Start a fresh chat thread and reference files explicitly.
- If nothing has helped, open a single package as the workspace and compare.
Stop at the step that fixes it. Most people never reach step seven.
FAQ
Does disabling codebase indexing make Cursor faster? It reduces background work and initial sync time, but it also removes the retrieval that makes chat useful on a repository you cannot fit in a prompt. Narrowing the index is almost always better than turning it off.
Why is Cursor slow only right after I switch branches? A large diff invalidates a large portion of the index, so it re-syncs. This is expected. If it happens constantly, your ignore rules are probably letting generated output into the index, and every build looks like a huge change.
Will a faster machine solve this? Sometimes, and less often than people expect. Watcher storms and whole-workspace language server analysis scale with file count, not with your CPU. More RAM helps if you are genuinely paging; it will not fix a misconfigured workspace.
Are these settings safe to commit for the team? Watcher, search, and file exclusions belong in the repository's workspace settings, since they benefit everyone. Memory ceilings and extension choices are personal and belong in your user settings.
How do I know a change actually worked? Pick one measurable thing before you start: seconds to open the workspace, CPU at idle in the process explorer, or latency until the first token of a chat response. Change one setting, measure again. Editor performance work is full of placebo, and a number is the cure.
One useful thing a week. Nothing else.
I test these tools on real work and write up what actually held up. No roundups I have not used, no affiliate padding. Unsubscribe in one click.
Related Posts
How to Connect Claude Code to a Custom MCP Server, Step by Step
September 4, 2026
Aider Alternative: The Best Free Terminal AI Coding Assistants in 2026
September 3, 2026
Cline vs Roo Code in 2026: Which Open Source AI Coding Agent Should You Actually Run?
September 2, 2026