Autonomous agents now in closed beta. Get early access Bito Ai

The context layer your coding agent is missing 

Technical design in hours, not days 

How Cursor’s codebase indexing works (2026 Guide) 

How Cursor's codebase indexing works

Table of Contents

Cursor turns your entire codebase into searchable context for the language model, so you can ask questions across your project without specifying files on every turn. Under the surface, this runs as a retrieval-augmented generation pipeline. 

Cursor chunks your code locally, embeds each chunk on its server, and stores the vectors in Turbopuffer. When you invoke @Codebase or press Cmd+Enter, your query embeds into the same vector space, Turbopuffer returns the most similar chunks, and the client reads the actual code from your local files into the prompt. 

The pipeline is fast at Cursor’s scale because of engineering choices that compound. AST chunking preserves semantic units through embedding, a Merkle tree keeps sync deltas small, and Turbopuffer’s object storage keeps idle codebases near zero cost. All of it starts on your machine. 

Two-panel flowchart showing Cursor's codebase indexing pipeline. Top panel shows the write path: files parsed by tree-sitter into semantic chunks, then encrypted paths and metadata sent to Cursor's embedding model, then stored in Turbopuffer with a namespace per codebase. Bottom panel shows the read path: a user query embedded, Turbopuffer runs a nearest-neighbor search, returns metadata as paths and line ranges, the client reads the corresponding local files, and the retrieved code plus the query become the prompt sent to the language model.

How Cursor represents your code 

On the client side, Cursor does two things before the sync loop touches the server. It chunks each file into semantically meaningful units, and it tracks the state of every file with a Merkle tree. Both feed the sync loop that pushes updates upstream. 

Chunking with AST awareness 

Cursor runs tree-sitter over each file to build an AST, walks the tree depth-first, and merges sibling nodes until each chunk lands under the embedding model’s token limit, typically around 500 tokens. 

The choice of AST-based over token-based splitting is one of those foundational calls that quietly determines everything downstream. Splitting by tokens or by line count would cut through the middle of a function. 

The embedding for that chunk would carry a broken semantic signal, because the function’s meaning depends on parts that ended up in other chunks. 

Splitting along syntactic boundaries produces coherent units instead, a function body, a class, or a config block. The embedding then represents something specific, which is what makes retrieval work at the chunk level in the first place. 

Each chunk travels with metadata: 

  • File path, obfuscated before it leaves the machine 
  • Start line and end line, so the server can point back to the right section on a query hit 
  • Content hash, which becomes the cache key for embeddings later in the pipeline 

The path obfuscation uses a specific scheme. Cursor splits the path along the ‘/’ and ‘.’ characters and encrypts each segment with a key that stays client-side, so the directory hierarchy stays visible to the server while the segment names stay hidden. 

Change detection through Merkle trees 

State tracking sits on top of the file hashes. Cursor builds a Merkle tree over your codebase, where each leaf is a file hash and each internal node hashes its children, so the root hash summarizes the entire tree in a single value. 

That property is what makes sync cheap. When Cursor syncs with the server, the client sends the root hash first, and if it matches the server’s copy, nothing else moves. If it differs, the server walks the tree only where hashes differ and requests updates for the leaves that changed, re-embedding only those chunks. 

The compression is what makes this feasible at production sizes. A workspace with 50,000 files carries about 3.2 MB of raw file hash data, which the client would ship on every sync without a Merkle tree in place. With the tree, most updates travel with a small delta of a few changed leaves. 

Sync runs on a roughly five-minute cadence. Chunks whose hashes changed since the last sync get re-embedded, and the rest reuse cached embeddings from prior runs, keyed by the content hash from chunking. 

The embedding index and how queries resolve 

With chunks in hand and state tracked in the Merkle tree, the work moves to Cursor’s server. This is where the pipeline earns the retrieval-augmented part of its name, with the embedding model and Turbopuffer doing the heavy lifting. 

Where the embeddings live 

Chunks travel from your machine to Cursor’s server, where the embedding model turns each chunk into a vector. 

Cursor uses a proprietary embedding model, with fallback to OpenAI’s embedding API in some configurations, and recent product changes suggest the proprietary model is trained on agent session data to sharpen code-specific retrieval quality. 

Once the vector is generated, the raw chunk text gets discarded. The vector plus metadata gets written to Turbopuffer, Cursor’s vector database, where the metadata carries the obfuscated path and line range so the server can point back to the right lines when a query hits, without ever holding the code itself. 

Turbopuffer’s architecture is why this scales economically: 

  • Object storage as the primary tier, S3 or GCS or the equivalent, rather than always-on SSD 
  • Namespace per codebase, so each codebase’s vectors are isolated 
  • Active namespaces load into memory or NVMe cache when a session starts 
  • Inactive namespaces fade back to object storage between sessions 
  • First query in a session takes roughly 300ms, subsequent queries hit cache at sub-10ms 

The namespace-per-codebase model is what makes it economically viable for Cursor to index millions of codebases automatically, because idle codebases cost almost nothing to keep around. 

How queries resolve 

The storage side handles the write path. The read path runs the same pipeline in reverse. 

  1. You invoke @Codebase or press Cmd+Enter 
  2. The client embeds your query using the same embedding model that indexed the codebase 
  3. The query vector goes to Turbopuffer, which runs a nearest-neighbor search across your namespace 
  4. Turbopuffer returns metadata: obfuscated paths and line ranges of the top matches 
  5. The client decrypts the paths and reads the referenced chunks from your local files 
  6. Retrieved chunks and query get assembled into the prompt 
  7. The prompt lands in the language model’s context window: the tokens the model has visible during response generation 

Cursor combines semantic search with lexical search in the same pipeline, because the two approaches find and miss different things. 

Approach Finds Misses 
Semantic search Code that means the same thing as your query, even when tokens differ Exact matches on specific identifiers 
Lexical search Exact token matches on identifiers Conceptual similarity across different vocabulary 

Cursor reports the hybrid combination lifts agent-eval performance by up to 23.5% over grep alone, and that semantic search on its own raises response accuracy by 12.5%. 

The lift is what justifies the RAG pipeline in the first place. The infrastructure cost is real, and the empirical case is that retrieval quality gets measurably better with these mechanisms than with grep or embeddings alone. 

How teams share indexes 

So far, this is the story for one developer on one codebase. At team scale, near-identical clones are common, and Cursor cites 92% average similarity across users within an organization. 

When you open a codebase for the first time, Cursor computes a similarity hash of your Merkle tree and looks for existing indexes in your team’s namespaces that match closely enough. 

If it finds a match above threshold, Cursor uses Turbopuffer’s copy_from_namespace to seed your namespace from your teammate’s index rather than re-embedding every chunk from scratch. The copy runs at a 50% write discount and happens in the background, and you can query the original index for immediate results while it completes. 

Flowchart showing how Cursor's team index reuse stays safe. When a teammate opens a codebase, their Merkle tree generates a similarity hash. Cursor looks up this hash against the team's existing namespaces, and if a close match exists, Cursor copies that index into the new user's namespace using Turbopuffer's copy_from_namespace at a 50% write discount. Every query result then goes through a verification step where the server checks whether the file's path hash exists in the client's Merkle tree. Results the client can prove access to are delivered. Results the client cannot prove access to are dropped.

The security implication is subtle. If a copied index contains code from a teammate’s branch you have no access to, letting you query that index would leak content, and Cursor solves this with Merkle tree content proofs, described in detail by their engineering team. 

Your client uploads its full Merkle tree with each request during the copy window. For every result the server considers returning, it checks that a hash in your tree matches the file’s path hash, and results your client fails to prove access to get dropped before they reach you. 

This is more careful engineering than most developer tools bother with at this layer. 

Once the background copy completes and your Merkle tree matches the server’s copy of your namespace, the content proofs become redundant, and the server operates on your synced index from that point. 

The configuration surface 

That is what the platform does on your behalf. What you can shape yourself is a smaller surface, split across two categories. Files that shape what gets indexed and how the agent behaves, and the @ symbol system that controls what enters the context window at query time. 

Configuration files 

.cursorignore in the project root excludes files from indexing, using syntax that matches .gitignore. Cursor respects .gitignore by default before layering .cursorignore on top, and common exclusions are node_modules, dist, .next, build artifacts, and large binaries. 

A well-tuned .cursorignore can drop the indexed file count by an order of magnitude on a large frontend project, and both initial indexing time and retrieval noise improve as a result. 

.cursorrules, along with the newer .cursor/rules/*.mdc format, holds project-specific instructions the agent reads on every turn, from coding conventions to architectural constraints to library preferences. 

Notepads are persistent reference documents you can @-mention on demand. Product requirements, architectural decisions, or coding conventions that need to stay accessible across chat sessions live in notepads rather than in chat history. 

The @ symbol system 

At query time, the @ symbol system controls what enters the context window. 

Symbol Purpose 
@Codebase Runs the retrieval pipeline through Turbopuffer 
@Files References specific files directly, bypassing retrieval 
@Code References a specific block, useful when you know the exact function you want in scope 
@Docs Pulls from documentation you have added to the project 
@Web Fetches URLs live at query time 
@Definitions Adds nearby definitions to context, available in Cmd+K only 

The index status sits in the status bar, and Cursor Settings → Indexing & Docs opens the full inventory of what is indexed. The “View included files” panel surfaces the actual file list after .cursorignore and .gitignore are applied, which is the fastest way to check that your configuration behaves the way you expect. 

Elevating Cursor’s indexing with Bito’s AI Architect 

Cursor’s pipeline works well for what it was built for. The ceiling shows up when a change spans multiple services, when the reasoning lives in Jira and Slack, or when a refactor needs a dependency graph rather than similar-looking chunks. 

Bito’s AI Architect fills that gap by running alongside Cursor’s retrieval with a typed knowledge graph. Classes, functions, and APIs connect through dependency, dataflow, and call-chain edges, and tickets from Jira, Slack threads, and Confluence docs enter the same graph. 

Cursor queries this graph through MCP, and the agent grounds every change in what the graph returns. When you modify an API contract, it names every downstream consumer deterministically. When you refactor a shared library, it traces the full call chain across services. When you ask why a defensive check exists, it returns the ticket that shaped it. 

Cursor’s retrieval handles fast local queries on semantically similar chunks. AI Architect handles cross-repo reasoning, deterministic impact analysis, and the business context that sits outside code. 

Bottom line 

Cursor’s codebase indexing delivers a fast, cost-efficient RAG pipeline through AST chunking, Merkle trees, Turbopuffer on object storage, hybrid retrieval, and team-index content proofs. Each choice solves a distinct problem, and together they set the ceiling on where the pipeline works well. 

Where this pipeline meets larger codebases, monorepos, and cross-repo work is a separate discussion, and Cursor’s limits on large codebases and monorepos picks up from here. 

Teams weighing Cursor against other AI coding IDEs often start with top Cursor alternatives or a specific head-to-head like GitHub Copilot vs Cursor, depending on how narrow the comparison needs to be. 

Picture of Akanksha Choudhary

Akanksha Choudhary

As Bito’s Lead Engineer, Akanksha brings over eight years of experience building and scaling backend systems across fintech, conversational AI, and e-commerce domains. She is passionate about code quality, thoughtful reviews, and improving developer productivity, with a strong focus on backend infrastructure and system design. Akanksha enjoys helping teams build reliable, scalable software and ship with confidence.

Picture of Amar Goel

Amar Goel

Amar is the Co-founder and CEO of Bito. With a background in software engineering and economics, Amar is a serial entrepreneur and has founded multiple companies including the publicly traded PubMatic and Komli Media.

Written by developers for developers red heart icon

This article is brought to you by the Bito team.

Latest posts

78% of your AI coding bill is the agent looking for your code

Code graphs explained for AI coding tools (2026 Guide)

The next big lever on AI spend sits between your coding agent and the model

Cursor’s limits on large codebases and monorepos

How Cursor’s codebase indexing works (2026 Guide) 

Top posts

78% of your AI coding bill is the agent looking for your code

Code graphs explained for AI coding tools (2026 Guide)

The next big lever on AI spend sits between your coding agent and the model

Cursor’s limits on large codebases and monorepos

How Cursor’s codebase indexing works (2026 Guide)