How ripgrep's `--quit-after-match` Flag Improves Search Performance

The --quit-after-match flag optimizes ripgrep's performance by immediately terminating the entire search process as soon as any match is found, eliminating unnecessary file I/O, CPU-intensive pattern matching, and parallel traversal overhead.

The --quit-after-match option in BurntSushi/ripgrep is designed for scenarios where you only need to verify that a pattern exists rather than finding every occurrence. By short-circuiting the search loops at the core execution level, this flag can dramatically reduce runtime when scanning large codebases.

What --quit-after-match Does

When enabled, --quit-after-match instructs ripgrep to stop searching immediately after the first match is detected anywhere in the directory tree. This behavior is exposed internally through the quit_after_match field in the HiArgs configuration struct, accessed via the quit_after_match() getter method defined in crates/core/flags/hiargs.rs (lines 86-88).

Unlike --max-count which limits matches per file, this flag terminates the entire search operation across all files and threads.

Implementation Details in the Source Code

The early-exit logic is implemented at three critical points in crates/core/main.rs, ensuring the optimization applies regardless of which search mode ripgrep uses.

Single-Threaded Search Termination

In the sequential search path, ripgrep checks the flag immediately after processing each file. If a match was found and the flag is set, the loop breaks instantly:

// crates/core/main.rs, lines 139-141
if matched && args.quit_after_match() {
    break;
}

This prevents the searcher from opening or reading any subsequent files in the queue.

Parallel Directory Traversal

For multi-threaded searches using the parallel walker, the implementation uses an atomic boolean to coordinate early termination across worker threads. When the flag is enabled and a match occurs, the walk state transitions to WalkState::Quit:

// crates/core/main.rs, around line 212
if matched.load(Ordering::SeqCst) && args.quit_after_match() {
    WalkState::Quit
}

This signals the thread pool to stop processing new directory entries immediately, eliminating synchronization overhead and thread spawning costs for remaining files.

File-Listing Mode

Even when running in file-listing mode (outputting only filenames), ripgrep respects the flag:

// crates/core/main.rs, lines 47-49
if args.quit_after_match() {
    break;
}

This ensures consistent behavior whether you are searching content or simply enumerating matching paths.

Performance Impact Analysis

The --quit-after-match flag delivers performance gains through four primary mechanisms:

  • Reduced I/O overhead: As soon as a match is detected, ripgrep stops opening further files, minimizing disk access and directory traversal operations.
  • Decreased CPU utilization: The matcher (grep::matcher) and searcher (grep::searcher) components are not invoked on remaining files or later lines within the current file once a match is found.
  • Early parallel walk termination: By returning WalkState::Quit, all worker threads stop processing new entries immediately, which eliminates the overhead of spawning further threads or synchronizing results for the remaining file tree.
  • Optimized existence checks: For use cases like verifying license headers or checking for forbidden patterns, runtime scales with the position of the first match rather than the total repository size.

Note: If you request statistics via --stats, the flag is ignored to ensure accurate aggregation, as noted in the comments within hiargs.rs.

Practical Usage Examples

Use this flag when you only need to know whether a pattern exists:


# Stop after finding the first TODO comment

rg --quit-after-match "TODO" src/

Combine with --quiet for fast exit-status checks in scripts:


# Check if unsafe code exists in the project

if rg --quiet --quit-after-match "unsafe" "$PROJECT/src"; then
    echo "Unsafe code detected"
fi
echo $?   # Returns 0 if match found, 1 if no match

For CI pipelines that need to verify file existence without listing all matches:


# Fast check for license headers in large repositories

rg --quit-after-match --files-with-matches "Copyright" . || echo "Missing copyright notices"

Summary

  • The --quit-after-match flag short-circuits ripgrep's search immediately upon finding the first match, as implemented in crates/core/main.rs.
  • It reduces I/O, CPU usage, and parallel coordination overhead by breaking out of search loops or returning WalkState::Quit in directory traversal.
  • The optimization applies consistently across single-threaded, parallel, and file-listing modes.
  • This option is ideal for existence checks in large codebases where full result sets are unnecessary.

Frequently Asked Questions

Does --quit-after-match work with the --stats flag?

No. According to the source code in crates/core/flags/hiargs.rs, when --stats is requested, ripgrep ignores the --quit-after-match flag to ensure complete statistical aggregation. The search will continue through all files to generate accurate match and performance statistics.

How does --quit-after-match differ from --max-count?

The --max-count (or -m) flag limits the number of matches displayed per file but continues searching all files. In contrast, --quit-after-match terminates the entire search process across all threads and files immediately after the first match is found anywhere in the search space.

Can I use --quit-after-match with parallel searches?

Yes. The flag is fully compatible with ripgrep's parallel search implementation. In crates/core/main.rs (around line 212), the code checks an atomic boolean representing the match state and returns WalkState::Quit to halt the parallel directory walker, ensuring all worker threads stop processing new files immediately.

What exit code does ripgrep return when using --quit-after-match?

When combined with --quiet (or -q), ripgrep returns exit code 0 if a match was found and 1 if no matches were found in the searched files. This behavior makes the flag particularly useful for shell scripts that need to check for pattern existence without processing output, as the search terminates as soon as the exit status can be determined.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →