StackMap
Subscribe
Explore / tgrep
microsoft

tgrep

Microsoft's trigram-indexed grep: a client/server index narrows each regex to candidate files. Powers search in GitHub Copilot CLI; ships MCP tools and hooks for Codex and pi. Rust.

3,366 135 Rust MITupdated 2 days ago
View on GitHubDispute this mapping →
Curator's take

Use tgrep when ripgrep itself is the slow part — big monorepos where agents grep constantly. A trigram index narrows each regex to candidate files and a background server keeps it fresh; Microsoft's own sweep has it beating ripgrep in 17 of 18 repo/platform cases with a warm index (up to ~52x). It's what GitHub Copilot CLI uses under the hood, and an installer adds MCP search tools for Codex and pi. Mind the trade-offs: the index can lag the filesystem (use --no-index when you need what's on disk right now), patterns without useful trigrams still scan everything, and index, serve and search need matching flags. On a normal-sized repo ripgrep is already fast enough; for search by meaning use a semantic index instead.

Mapped by ShipWithAI editors · links verified

Continue your stack

What teams reach for next — and why each earns a place beside tgrep. Ranked by curator confidence.

pairs wellpairs wellpairs wellalternativecocoindex-codegraphifyserenazvec-greptgrep
pairs wellalternativebuilt withpick a node for the why · open it from the panel
Weekly digest
README.md3 min read

tgrep

Trigram-indexed grep with a client/server architecture for fast regex search in large codebases.

tgrep is integrated into GitHub Copilot CLI to power fast grep searches across large repositories.

Quick start

Install tgrep, then start a server:

tgrep serve .           # builds the index if needed; runs in the foreground

In another terminal:

tgrep -- "fn main" .    # automatically connects to the server
tgrep status .          # show indexing and refresh status

Without a server, run tgrep index . to build an on-disk index. Searches use the server when available, then the local index, or scan the filesystem if no usable index exists. Indexes are stored in .tgrep/ by default; add this directory to .gitignore.

Indexes can lag filesystem changes. The server updates asynchronously; without a server, rerun tgrep index . after changes. Use --no-index when a search must read the current files. Queries scan during an initial build until complete coverage is available.

For coding agents, see AGENTS.md. To install MCP search tools and startup hooks for Codex or pi, run bash install-agent.sh from this checkout (Linux/macOS, Python 3.11+). See the agent integration guide.

Performance

A trigram index narrows each query to files that could match, then verifies those files with the regex engine in parallel. Patterns without useful trigrams may still require searching every indexed file.

In the August 24, 2026 benchmark sweep, tgrep was faster than ripgrep in 17 of 18 repo/platform combinations, with speedups from 0.93x to 51.9x. These measure client/server search latency with the index already built, not indexing time. Results depend on the query, repository, storage, and match volume. See BENCHMARKS.md for measurements and methodology.

Usage

Build the index

tgrep index .                        # index current directory
tgrep index /path/to/repo             # index a specific repo
tgrep index . --index-path /tmp/idx    # custom index location
tgrep index . --exclude vendor --exclude third_party  # skip directories

Each build reports elapsed time and, where available, peak memory:

Index built successfully at /tmp/idx
Indexed in 22.6s using external strategy (peak memory 160.1 MiB)

Windows reports peak private committed bytes; Linux samples anonymous resident memory. Both exclude file-backed mappings and report the working set separately when it is substantially larger. macOS reports resident memory instead.

Repositories without a .git directory

Like ripgrep, tgrep applies .gitignore only inside a Git repository. It warns when a root .gitignore is present but not applied. Use --no-require-git on indexing, serving, and searching to apply those rules outside Git:

tgrep index . --no-require-git
tgrep serve . --no-require-git
tgrep --no-require-git -- "pattern" .

Case-insensitive repositories

When Git's core.ignorecase is enabled, tgrep applies an additional case-insensitive exclusion pass for the repository's root .gitignore and .git/info/exclude. Git-tracked paths are exempt from this additional pass, but not from ordinary traversal, binary, or size filtering.

Nested .gitignore files and global ignore rules do not get this additional pass. --no-ignore disables it along with the normal ignore rules.

Keep index and serve flags in step

Use the same --no-require-git, --no-ignore, --max-filesize (or --no-max-filesize), and --exclude settings for index and serve. Startup reconciliation removes indexed files excluded by the server's current settings. For example, serving an uncapped index with --max-filesize 8M removes files larger than 8 MiB from that index.

Pass the same size policy, --no-require-git, and any custom --index-path to searches too. --exclude is o