Skip to main content
v2026.11,772 entries · CC-BY 4.0

BAM Index (.bai) Files: Why You Need One and How to Build It

Why a BAM file needs a coordinate-sorted .bai index for fast region queries, how to build one with samtools index, and what breaks when the index is missing or stale.

Written and maintained by CASRAI Editorial Board

Last updated

A BAM file can hold tens of millions of aligned reads, and most of the tools that consume it never need to read all of them at once. A genome browser opening a single gene, a variant caller restricted to an exome panel, or a QC step checking coverage over one region all need the same thing: the alignments that overlap a specific stretch of a reference sequence, retrieved without scanning past everything that comes before it in the file. That capability doesn’t come from the BAM file itself — it comes from a separate index file, .bai, built on top of it. Without that index, “give me chr7:140,453,136-140,624,564” and “give me the whole file” cost roughly the same amount of I/O.

What the .bai index actually does

Per the SAM/BAM format specification maintained by the samtools/hts-specs project, the purpose of indexing is stated directly: it aims “to achieve fast retrieval of alignments overlapping a specified region without going through the whole alignments.” The BAI format does this with two complementary structures layered over the BGZF-compressed BAM body:

  • A binning index, based on the UCSC genome-browser binning scheme. The reference is divided into a hierarchy of bins — the spec allows bins spanning 229, 226, 223, 220, 217, or 214 bp — and every alignment is assigned to the smallest bin that fully contains it. A region query only has to inspect the handful of bins that overlap the requested interval, not every alignment in the file.
  • A linear index, which supplements the bins by recording a compressed file offset for every 16 kbp window along each reference sequence. This lets a lookup skip directly past the parts of the file that can’t possibly contain the requested region, avoiding otherwise-necessary bin-overlap checks against alignments that start well upstream of it.

Both structures store virtual file offsets into the underlying BGZF block structure, not byte positions in an uncompressed stream — which is also why an index built for one BAM’s exact byte layout is meaningless against a different byte layout, a point that matters later in this guide. One structural limit worth knowing: because BAI’s largest bin tops out at 229 bp, the spec notes plainly that “this index format does not support reference chromosome sequences longer than 229-1″ (about 536.8 Mbp). The CSI index format (.csi) generalizes the bin sizes and removes that ceiling, which is why some very large plant and animal genome references require .csi instead of .bai.

Why genome browsers and downstream tools require it

Random access by region is not an optimization these tools can skip — for many of them it’s the only access pattern they support. IGV and other genome browsers load a BAM track by jumping straight to the visible window; they are not built to stream and discard everything upstream of it, and most refuse to load a BAM track at all without a matching index present alongside it. The same is true for command-line region queries — samtools view aln.bam chr1:1000000-2000000, samtools depth -r, bcftools mpileup -r, and interval-restricted steps in variant-calling pipelines all depend on the index to resolve a region argument into a set of file offsets before they read a single alignment. Take the index away and these either error immediately or fall back to a full sequential scan, which defeats the reason region-restricted execution was used in the first place on a file that can run into the tens of gigabytes.

The prerequisite: the BAM must be coordinate-sorted

Indexing only works because the binning and linear-index structures assume alignments appear in the file in a predictable order. The spec is explicit about this: “BAM must be sorted by the reference ID and then the leftmost coordinate before indexing.” A coordinate-sorted BAM records that fact in its own header as @HD SO:coordinate. Feed samtools index a name-sorted or unsorted BAM and it will not produce a usable index — sort first with samtools sort, then index the sorted output:

samtools sort -o aln.sorted.bam aln.bam
samtools index aln.sorted.bam

This ordering requirement is also why sorting and indexing are treated as one inseparable step in almost every alignment pipeline: an aligner’s raw output stream is typically read-name ordered (or unordered across threads), and it has to pass through samtools sort before an index is even a meaningful next step.

Creating the index with samtools index

The reference implementation, samtools index, produces a .bai file by default:

samtools index aln.sorted.bam
# produces aln.sorted.bam.bai

Two flags matter beyond the default case. -c/--csi builds a CSI index instead (minimum bin size 214 by default), and -m INT builds a CSI index with a specified minimum interval size (2INT) — use either when a reference sequence exceeds BAI’s ~536.8 Mbp ceiling, or when working with a downstream tool that specifically expects .csi. samtools index also indexes CRAM (producing .crai) and BGZF-compressed SAM using the same command. If samtools isn’t already available in your environment, it installs cleanly via Bioconda (conda install -c bioconda samtools) or a system package manager on most HPC systems.

What breaks when the index is missing

The failure mode depends on the tool, and none of the three outcomes are good:

  • Outright refusal. Genome browsers including IGV, and many samtools/bcftools subcommands invoked with a region argument, will error immediately if no .bai/.csi is found next to the BAM. This is the safest failure mode — it’s loud and it stops the run before anything downstream can be wrong.
  • Silent fallback to a full scan. Some tools that can technically operate without an index will do so by reading the entire file sequentially and filtering in memory. The result is still correct, but on a large BAM this can turn a sub-second lookup into a multi-minute (or multi-hour, at cluster scale, repeated across thousands of region queries) operation with no error to flag that something regressed.
  • A pipeline step that assumes indexing already happened. Workflow managers and multi-step scripts frequently call samtools index as an explicit, separate line after alignment and sorting. Drop that line, or reorder steps so a merge or filter runs after indexing instead of before it, and the very next step that needs the index either fails loudly (best case) or is quietly handed no region restriction at all.

What breaks when the index is stale

This is the more dangerous case, because a stale index doesn’t always announce itself. A .bai file encodes virtual file offsets that are only valid for the exact byte layout of the BAM it was built from. If the underlying BAM changes — re-sorted, re-headered, had reads added or removed by filtering, or replaced by a merge of several BAMs — and the old .bai is left in place (or, worse, a new BAM is written over the old filename without a fresh index), the offsets in that index no longer point to the right place in the new file. Depending on how far the byte layout shifted, region queries against a stale index can return the wrong reads, an incomplete set of reads, or in some cases fail outright once the index directs a seek past the end of the (now shorter) file. Many htslib-based tools compare the index’s and the BAM’s modification times and will warn when the index looks older than the data file it’s paired with — a useful safety net, but not a substitute for re-indexing, since that check is easy to defeat inadvertently (a file copy or rsync that preserves or resets timestamps inconsistently) and isn’t implemented uniformly across every consumer of the index.

Re-index after any BAM modification — not just after sorting

The operational rule is simple and worth stating explicitly, because it’s the step that gets skipped under deadline pressure: any operation that rewrites a BAM’s contents invalidates its existing index, and the index must be rebuilt before the file is used for a region query again. That includes, at minimum:

  • Filtering reads (e.g. samtools view -b -q 20, duplicate marking/removal, or removing unmapped/secondary alignments).
  • Merging multiple BAMs into one (samtools merge).
  • Re-sorting or re-headering a previously sorted file.
  • Any read-group edit, coordinate liftover, or base-quality recalibration step that rewrites the alignment records themselves.

The fix is one line, run as the last step after any of the above:

samtools index filtered.bam

Building that line into the pipeline itself — rather than into a checklist a person has to remember — is the only reliable way to avoid shipping a stale index; workflow-manager rules (Snakemake, Nextflow) are commonly written so the index is a declared output of the same rule that produces the modified BAM, which forces regeneration whenever the BAM output changes.

Frequently asked questions

Do I need to index a BAM if I’m only running whole-file, non-region-restricted analysis?

Not strictly — a tool that reads a BAM start to finish (counting all reads, generating whole-genome coverage, or converting formats) doesn’t need random access and can run without an index. Many pipelines index anyway, because a downstream step or a QC visualization almost always ends up needing region access later, and it’s cheaper to build the index once than to discover the gap mid-pipeline.

What’s the difference between .bai and .csi, and which one should I use?

Both are region-query indexes for a coordinate-sorted BAM; .bai is the original format and the default samtools index output, while .csi generalizes the bin sizes to support reference sequences longer than BAI’s roughly 536.8 Mbp limit. Use .csi (via samtools index -c) only when a specific reference sequence in your file exceeds that limit, or a downstream tool explicitly requires it; otherwise the default .bai is the more widely supported choice.

Can I just rename or copy an existing .bai to match a renamed BAM?

No. The index is tied to the byte layout of the specific BAM file it was built from, not to the filename. Renaming both the BAM and its index together (so the .bai keeps matching <bam-filename>.bai) is fine; pairing an index built from one BAM’s content with a different or modified BAM’s content, even under the matching filename, produces the stale-index failure described above.

Why does samtools refuse to index my BAM with an error about sorting?

The binning and linear-index structures the SAM/BAM specification defines only work when alignments are ordered by reference ID and then leftmost coordinate. If the BAM is name-sorted (a common intermediate state right after some aligners, and required by certain paired-end tools) or unsorted, run samtools sort first to produce a coordinate-sorted BAM, then index that output.

Does the BAM file need to be present for the index to work, or is the index self-contained?

The index is only ever used alongside its BAM — it stores offsets into the BAM’s compressed data, not the alignment records themselves. Tools open both files together (conventionally, the index sits next to the BAM as <filename>.bam.bai) and use the index purely to decide which parts of the BAM to read.

Related reading

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · included with Regulatory Radar

Ask about BAM Index (.bai) Files: Why You Need One and How to Build It

Ask CASRAI answers research-administration questions and cites the passages behind every claim — and says so when the corpus does not cover something, instead of guessing. It comes with a Regulatory Radar subscription at $29 a month, alongside the daily digest of regulatory changes and the dashboard of what changed.

150 questions a day, on this site, over the API, or inside your own tools through the CASRAI MCP server.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →

Regulatory Radar

Stop finding out after the fact

$29/month, cancel anytime. Daily digest updates from our analysis, a dashboard holding the same items, and a cited assistant for everything they raise.

  • Federal Register, Federal Register+, Grants.gov, Regulations.gov, NSF News, UKRI, plus CASRAI’s own published content.
  • 72,264 indexed passages, and every answer cites the ones it drew on.