# How to Use the fzf --tiebreak Option to Control Result Sorting

> Master fzf --tiebreak to refine search results. Learn how secondary sorting criteria like length and chunk improve your fzf experience and control result order effectively.

- Repository: [Junegunn Choi/fzf](https://github.com/junegunn/fzf)
- Tags: how-to-guide
- Published: 2026-03-01

---

**The `--tiebreak` option in fzf specifies secondary sorting criteria used to order results when multiple items receive identical fuzzy-match scores, accepting a comma-separated list of up to three values from `length`, `chunk`, `pathname`, `begin`, `end`, and `index`.**

The `junegunn/fzf` command-line fuzzy finder ranks search results using a scoring algorithm that evaluates how closely each item matches the query pattern. When two or more candidates achieve the same fuzzy score, the `--tiebreak` option determines their relative order by applying additional comparison criteria. Understanding how this sorting mechanism works allows you to customize result ordering to match your specific workflow, whether you prefer shorter filenames, matches clustered together, or preserving input sequence.

## What Is the fzf --tiebreak Option?

The `--tiebreak` option defines a **priority list of secondary sorting criteria** that fzf applies after computing the primary fuzzy-match score. By default, fzf uses `length` as the sole tiebreaker, meaning that when scores are equal, shorter entries appear before longer ones.

You can specify multiple criteria as a comma-separated list (maximum of three criteria besides the mandatory score), and fzf evaluates them in the order provided. For example, `--tiebreak=chunk,length` first compares the size of the matching chunk, then falls back to line length if the chunk sizes are identical.

## Available Tiebreak Criteria

The `junegunn/fzf` source code defines six distinct criteria you can use with `--tiebreak`. Each criterion computes a specific metric that influences the final sort order:

### length

**`length`** compares the trimmed length of the candidate line. Shorter lines receive higher priority (are sorted earlier). This is the default behavior when no `--tiebreak` option is specified.

### chunk

**`chunk`** measures the size of the smallest contiguous "chunk" that contains all matched characters. Smaller chunks indicate that the match characters are clustered together rather than scattered across the string, which typically represents a more relevant match.

### pathname

**`pathname`** calculates the distance from the last path separator to the start of the match. This criterion prioritizes matches that appear closer to the end of file paths (the filename itself), making it useful when searching through directory structures.

### begin

**`begin`** measures the distance from the start of the line to the first matched character. Lower values (matches closer to the beginning) receive higher priority.

### end

**`end`** uses the inverse of the distance from the end of the line to the last matched character. Matches closer to the end of the line receive higher priority.

### index

**`index`** preserves the original input order. Because this criterion acts as a final fallback, it must be the last item in your `--tiebreak` list if included. It ensures deterministic ordering when all other metrics are equal.

## How Tiebreak Sorting Works Internally

Understanding the internal implementation helps clarify why the `--tiebreak` option behaves the way it does. The sorting mechanism involves three main components in the `junegunn/fzf` codebase: option parsing, criteria propagation, and result scoring.

### Parsing and Validation in options.go

When you provide `--tiebreak` on the command line, the parser in [`src/options.go`](https://github.com/junegunn/fzf/blob/main/src/options.go) invokes the `parseTiebreak` function (lines 1306–1362). This function:

- Splits the comma-separated list into individual criteria
- Validates that no duplicates exist
- Ensures you specify at most three criteria (besides the mandatory score)
- Verifies that `index` appears last if present, since it serves as the final fallback

The validated list is stored in `opts.Criteria` for later use.

### Criteria Propagation in core.go

After parsing, [`src/core.go`](https://github.com/junegunn/fzf/blob/main/src/core.go) (line 79) copies the criteria list from the options structure to a package-level variable named `sortCriteria`. This makes the tiebreak configuration available to the scoring logic during the search execution.

### Scoring and Point Allocation in result.go

The actual sorting comparison happens in [`src/result.go`](https://github.com/junegunn/fzf/blob/main/src/result.go) within the `buildResult` function (lines 52–108). Each candidate match is transformed into a `Result` structure containing four 16-bit unsigned integers called `points`.

The function iterates over `sortCriteria` and fills the `points` array in reverse order (`result.points[3-idx] = val`). This encoding strategy allows fzf to compare results as a single 64-bit big-endian unsigned integer, where earlier criteria occupy higher-order bits and therefore dominate the comparison.

The specific metrics computed include:

- **byScore**: `max_uint16 - score` (higher original scores produce larger values)
- **byLength**: Trimmed line length (shorter lines get larger values)
- **byChunk**: Size of the smallest chunk containing all matches
- **byPathname**: Distance from last path separator to match start
- **byBegin**: Distance from line start to first match character
- **byEnd**: Inverse distance from line end to last match character
- **byIndex**: Original input index (final fallback)

## Practical Examples

These command-line examples demonstrate how different `--tiebreak` configurations affect result ordering in real-world usage.

Prefer shorter filenames when scores are equal:

```bash
fzf --tiebreak=length

```

Prioritize matches where query characters appear close together, falling back to shorter lines:

```bash
fzf --tiebreak=chunk,length

```

Favor matches appearing in the filename portion of paths (useful for file searching):

```bash
fzf --tiebreak=pathname

```

Preserve the original file list order when all other metrics tie:

```bash
fzf --tiebreak=index

```

Combine up to three criteria, ensuring `index` remains last:

```bash
fzf --tiebreak=chunk,pathname,index

```

## Summary

- The **fzf `--tiebreak` option** defines secondary sorting criteria applied when candidates receive identical fuzzy-match scores.
- The default value is `length`, causing shorter entries to appear first during ties.
- Available criteria include `length`, `chunk`, `pathname`, `begin`, `end`, and `index`, which can be combined in comma-separated lists of up to three items.
- The implementation encodes criteria into a 64-bit integer in [`src/result.go`](https://github.com/junegunn/fzf/blob/main/src/result.go), allowing efficient comparison during the search process.
- Criterion `index` must always appear last in the list and serves as the final fallback to preserve input order.

## Frequently Asked Questions

### What is the default tiebreak behavior in fzf?

By default, fzf uses `--tiebreak=length`. When two or more items achieve the same fuzzy-match score, the shorter line appears first in the results. This default prioritizes concise matches over longer strings containing the same pattern.

### Can I use multiple tiebreak criteria at once?

Yes, you can specify up to three criteria as a comma-separated list. For example, `--tiebreak=chunk,pathname,length` first compares chunk size, then pathname proximity, then line length. The `index` criterion must always be last if included, as it acts as the final fallback.

### Why does the index criterion have to be last?

The `index` criterion represents the original input order and serves as the ultimate tiebreaker when all other metrics are equal. The parser in [`src/options.go`](https://github.com/junegunn/fzf/blob/main/src/options.go) enforces this constraint because `index` provides deterministic ordering only when applied after all qualitative comparisons have failed to distinguish candidates.

### How does chunk tiebreaking differ from length tiebreaking?

While `length` simply compares the total trimmed length of the candidate line, `chunk` measures the size of the smallest contiguous substring containing all matched characters. A smaller chunk indicates that the query characters appear clustered together rather than scattered across the line, which often signals a more relevant match even if the total line length is longer.