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

> Learn how ripgrep's --quit-after-match flag boosts search performance by stopping instantly after the first match, reducing I/O and CPU usage for faster results.

- Repository: [Andrew Gallant/ripgrep](https://github.com/BurntSushi/ripgrep)
- Tags: performance
- Published: 2026-03-05

---

**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`](https://github.com/BurntSushi/ripgrep/blob/main/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`](https://github.com/BurntSushi/ripgrep/blob/main/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:

```rust
// 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`:

```rust
// 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:

```rust
// 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`](https://github.com/BurntSushi/ripgrep/blob/main/hiargs.rs).

## Practical Usage Examples

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

```bash

# Stop after finding the first TODO comment

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

```

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

```bash

# 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:

```bash

# 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`](https://github.com/BurntSushi/ripgrep/blob/main/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`](https://github.com/BurntSushi/ripgrep/blob/main/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`](https://github.com/BurntSushi/ripgrep/blob/main/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.