BAM File Size Calculator: Estimate Storage Needs Before Alignment

By Dr. Zubair Khalid, DVM, MS, PhD ·

BAM File Size Calculator: Estimate Storage Needs Before Alignment

By the end of this guide, you will be able to produce a defensible BAM storage estimate before you start alignment. You will know how to turn a reference size, a target coverage, a read length, and a small pilot BAM into a disk-space number. You will also know which parts of the estimate are hard measurements and which parts are assumptions that need a margin.

Have these items on hand: the reference FASTA and its .fai index, a FASTQ file or a read count, a small pilot BAM or SAM from the same library type, samtools, and Python 3. A pilot BAM is a small alignment produced from the same organism, library prep, read length, and processing path as the full project. It does not need to be large. It needs to be representative.

A BAM file is the binary, block-compressed representation of SAM, the text alignment format used in next-generation sequencing pipelines [1]. SAM stores alignment records as tab-delimited text. BAM stores the same records in a compact binary form and compresses the stream. FASTQ stores raw reads with per-base quality scores. FASTA stores sequences without per-base quality and is the usual container for a reference genome. Coverage is the average number of times each reference base is covered by aligned reads. Read length is the number of bases in one sequencing read.

Storage planning matters because SAM/BAM tools must manipulate large amounts of data, and memory management is a recognized challenge in that software class [1]. The same data volume that stresses memory during processing also occupies disk during alignment, sorting, duplicate marking, and archival. A quick estimate before alignment prevents the common failure mode of running out of space halfway through a pipeline.

What a BAM File Contains and Why Size Estimation Works

A BAM file has two major parts: a header and a series of alignment records. The header stores reference names and lengths, read-group metadata, program records, and other setup information. Each alignment record stores the read name, flag, reference name, position, mapping quality, CIGAR string, mate information, template length, sequence, quality string, and optional tags. The CIGAR string is the compact notation that describes alignment operations such as matches, insertions, deletions, and soft clipping. Optional tags carry caller-specific information such as edit distance, alignment score, CB and UB cellular barcode tags, or UMI tags.

BAM sequence is packed, quality scores are stored per base, and the full stream is compressed in blocks with BGZF, a gzip-compatible block format that allows random access. A separate BAI index, usually named sample.bam.bai, stores virtual offsets that let tools jump to genomic regions. The index is not part of the BAM file itself, but it belongs in the storage plan.

Size estimation works because most BAM bytes scale with the number of aligned records. The dominant drivers are:

  • The number of aligned reads.
  • The read length.
  • The quality-score distribution and encoding.
  • The length of read names.
  • The number of CIGAR operations, especially for spliced or gapped alignments.
  • The number and size of optional tags.
  • The compression level and the redundancy in the data.
  • The header size, which matters most for small BAMs and many-contig references.
  • The index size, which grows with reference length and alignment density.

BAM and SAM are standard alignment formats in next-generation sequencing pipelines [1]. BAM is usually smaller than SAM because it is binary and block-compressed. CRAM is a reference-based compressed alignment format that can reduce size further, but its savings depend on the reference, the preservation settings, and the downstream tools. A BAM calculator should not be treated as a CRAM calculator without a CRAM-specific pilot.

FASTQ versus FASTA matters here. FASTQ carries per-base quality strings. FASTA carries sequence only. A BAM file usually retains the quality string, so FASTQ quality distributions affect BAM size. A reference FASTA affects the header and the alignable target size, but it does not carry per-read quality. When you compare input size to output size, compare the right formats. A 100 GB FASTQ can produce a much smaller BAM, and a small FASTA can support a very large BAM.

The BAM File Size Calculator Estimate Formula

The practical formula has two measured inputs from a pilot and three project inputs from the experimental design. The pilot supplies bytes per aligned read and a compression ratio. The project supplies reference size, coverage, read length, and expected alignment fraction.

QuantitySymbolHow to get itNotes
Reference sizeGSum the length column in the .fai indexUse alignable target size for targeted assays
Target coverageCChosen experimental depth30x means 30 bases per reference base on average
Read lengthLFASTQ statistics after trimmingUse the length that will be aligned
Total readsNC × G / LFor paired-end data this is total reads, not pairs
Aligned fractionfPilot flagstat or prior dataValue from 0 to 1
SAM bytes per aligned readPPilot SAM text bytes divided by aligned readsInclude header for large-header cases
Compression ratioRPilot SAM text bytes divided by pilot BAM bytesDimensionless
BAM estimateS_bamN × f × P / RCore storage estimate
Index estimateIPilot index size scaled by aligned readsOr measure directly after alignment
Working overheadOChosen fraction of BAM sizeSorting, temporary files, duplicate marking
Total reserveS_totalS_bam + I + OAdd reference and archive copies if needed

The central formula is:

N = (C × G) / L
S_bam = (N × f × P) / R
S_total = S_bam + I + O

A first-principles version is useful when you cannot build a pilot. It replaces P with an estimate of uncompressed record bytes:

U = N × f × (F + name_len + cigar_bytes + seq_bytes + qual_bytes + tag_bytes)
S_bam = U / R

F stands for the fixed BAM record fields. name_len is the read-name length. cigar_bytes is four times the number of CIGAR operations. seq_bytes is approximately half the read length because BAM packs bases. qual_bytes is approximately the read length because quality scores are stored per base. tag_bytes covers optional tags. This version is more error-prone because real data has variable read names, clipping, and tags. Use it for a sanity check, not as the primary estimate.

Coverage is the anchor. If you know the target coverage, the reference size, and the read length, the total read count follows directly. A 30x experiment over 3.1 billion bases with 150 bp reads needs about 620 million reads:

N = (30 × 3,100,000,000) / 150 = 620,000,000 reads

For paired-end data, that is 310 million pairs. The total read count is what enters the BAM formula. A common mistake is to plug in the number of pairs and then halve the estimate by accident.

The aligned fraction f corrects for reads that do not map. If 95 percent of reads align, use 0.95. The formula uses N × f as the expected aligned record count. Reads that fail vendor checks, reads that are too short after trimming, and reads from contamination all reduce the aligned count. A pilot samtools flagstat gives a measured value for the same library type.

The compression ratio R is not a universal constant. It depends on quality-score entropy, read-name redundancy, duplicate rate, tag content, and compression level. Measure it from a pilot:

R = uncompressed SAM text bytes / BAM bytes

The numerator should come from samtools view -h pilot.bam | wc -c, which writes SAM text to standard output. The denominator should come from the actual BAM file size on disk. Do not use a FASTQ gzip ratio as a substitute. FASTQ and BAM have different redundancy structures.

The index term I is separate. A BAI index scales with reference length and alignment density. Measure the pilot index size, then scale by the ratio of full aligned reads to pilot aligned reads. For small projects, the index is a minor term. For large genomes and deep coverage, it deserves a line in the budget.

The overhead term O covers sorting temporary files, duplicate-marking intermediates, and space needed during merging. There is no universal percentage. Set it from your pipeline. A simple sort may need temporary space close to the input size. A workflow that writes SAM intermediates can need more. The calculator should make overhead explicit rather than hiding it in a vague margin.

Use consistent units. A decimal GB is 1,000,000,000 bytes. A binary GiB is 1,073,741,824 bytes. A 44.3 GB estimate is about 41.2 GiB. Reserve space in the same unit that your filesystem and scheduler report.

How to Calculate a BAM File Size Estimate Step by Step

This walkthrough uses a hypothetical human whole-genome project with 150 bp paired-end reads, 30x target coverage, and a pilot BAM from the same library. Replace the example numbers with your measurements.

Step 1: Measure the reference size

Index the FASTA and sum the lengths in the .fai file.

samtools faidx reference.fa
cut -f2 reference.fa.fai | awk '{s+=$1} END{print s}'

Expected output for the example reference:

3100000000

Use this value as G. For a targeted panel, use the alignable target size, not the whole genome, if you want a panel-specific estimate. For a whole-genome BAM, the full reference size is the right scale. If the reference has many unplaced contigs, the BAM header and index will include them. That affects header and index size but not the per-read record estimate.

Step 2: Count reads or compute them from coverage

If you already have FASTQ, count reads with awk. FASTQ has four lines per read.

zcat reads_R1.fastq.gz | awk 'END{print NR/4}'
zcat reads_R2.fastq.gz | awk 'END{print NR/4}'

Expected output for the example:

250000000
250000000

Total reads are 500,000,000. For paired-end data, pairs are 250,000,000. The BAM formula uses total reads.

If you do not have FASTQ counts, compute reads from coverage:

python3 - <<'PY'
G = 3100000000
C = 30
L = 150
print((C * G) / L)
PY

Expected output:

620000000.0

The two routes disagree in this example because the FASTQ count is a library-size measurement and the coverage calculation is a target. Use the FASTQ count when you have it. Use the coverage calculation for planning before libraries exist.

Step 3: Build a pilot BAM and measure bytes per read

Convert a small SAM to BAM, index it, and measure the uncompressed SAM text size, the BAM size, and the aligned record count.

samtools view -b -o pilot.bam pilot.sam
samtools index pilot.bam
samtools view -h pilot.bam | wc -c
stat -c%s pilot.bam
samtools view -c -F 4 pilot.bam

Expected output for the example:

250000000
71428571
950000

The first number is the uncompressed SAM text size in bytes. The second is the BAM file size in bytes. The third is the count of mapped records. -F 4 excludes unmapped reads because the SAM flag 4 marks an unmapped read.

Compute P and R:

python3 - <<'PY'
sam_bytes = 250000000
bam_bytes = 71428571
aligned_reads = 950000
P = sam_bytes / aligned_reads
R = sam_bytes / bam_bytes
print(f"P = {P:.1f} SAM bytes per aligned read")
print(f"R = {R:.2f} SAM bytes per BAM byte")
PY

Expected output:

P = 263.2 SAM bytes per aligned read
R = 3.50 SAM bytes per BAM byte

P includes the pilot header. For a full project with the same header, that is acceptable. For a tiny pilot or a very large header, measure the header separately and add it to the final estimate. The header does not scale with read count.

Step 4: Run the calculation

Use the measured values and the target design values.

python3 - <<'PY'
G = 3100000000
C = 30
L = 150
f = 0.95
P = 263.2
R = 3.5
index_fraction = 0.02
overhead_fraction = 0.10

N = (C * G) / L
aligned = N * f
bam = (aligned * P) / R
index = bam * index_fraction
overhead = bam * overhead_fraction
total = bam + index + overhead

for name, value in [
    ("total reads", N),
    ("aligned reads", aligned),
    ("BAM bytes", bam),
    ("index bytes", index),
    ("overhead bytes", overhead),
    ("total bytes", total),
]:
    print(f"{name}: {value:,.0f}")
PY

Expected output:

total reads: 620,000,000
aligned reads: 589,000,000
BAM bytes: 44,285,714,286
index bytes: 885,714,286
overhead bytes: 4,428,571,429
total bytes: 49,600,000,001

The BAM estimate is about 44.3 GB in decimal units. The total reserve is about 49.6 GB before reference files and archive copies. In binary units, the BAM is about 41.2 GiB.

Step 5: Add the pieces the core formula leaves out

The core formula covers the alignment records. Add these items when they apply:

  • The BAM index, if the pipeline writes one.
  • The reference FASTA and its index, if they live on the same volume.
  • Temporary files for sorting and duplicate marking.
  • A second copy if the workflow keeps raw BAM plus deduplicated BAM.
  • CRAM or archive copies if the project has a retention policy.
  • Logs, metrics, and quality-control outputs.

A storage request should name the volume and the retention period. A 50 GB estimate for one BAM becomes a different number when the pipeline keeps three intermediate BAMs and a duplicate-marked BAM.

Step 6: Check the estimate against the finished BAM

After alignment, compare the measured file size to the estimate. Use samtools flagstat for mapped counts, samtools idxstats for per-reference counts, samtools view -c -F 4 for mapped record count, and du -h for disk use.

samtools flagstat final.bam
samtools idxstats final.bam
samtools view -c -F 4 final.bam
du -h final.bam final.bam.bai

The mapped count should be close to N × f. If the finished BAM is much larger than the estimate, check the read-name length, optional tags, duplicate rate, and compression level. If it is much smaller, check whether the aligner filtered more reads than expected or whether the BAM was written at a higher compression level.

Build a Small BAM File Size Calculator in Python

The following script implements the pilot-based formula. It uses short command-line options to keep the commands simple. Save it as bam_size_estimate.py.

#!/usr/bin/env python3
import argparse

def human_bytes(n):
    units = ["B", "KB", "MB", "GB", "TB", "PB"]
    i = 0
    x = float(n)
    while x >= 1000 and i < len(units) - 1:
        x /= 1000.0
        i += 1
    return f"{x:.2f} {units[i]}"

def main():
    p = argparse.ArgumentParser(
        description="Estimate BAM storage before alignment"
    )
    p.add_argument("-g", type=float, required=True,
                   help="Reference size in bp")
    p.add_argument("-c", type=float, required=True,
                   help="Target coverage, for example 30")
    p.add_argument("-l", type=float, required=True,
                   help="Read length in bp")
    p.add_argument("-f", type=float, default=1.0,
                   help="Expected aligned fraction from 0 to 1")
    p.add_argument("-p", type=float, required=True,
                   help="Uncompressed SAM bytes per aligned read")
    p.add_argument("-r", type=float, required=True,
                   help="SAM text bytes divided by BAM bytes")
    p.add_argument("-i", type=float, default=0.0,
                   help="Index size as a fraction of BAM size")
    p.add_argument("-o", type=float, default=0.0,
                   help="Working overhead as a fraction of BAM size")
    args = p.parse_args()

    if args.aligned_fraction < 0 or args.aligned_fraction > 1:
        raise SystemExit("aligned fraction must be between 0 and 1")
    if args.read_length <= 0:
        raise SystemExit("read length must be greater than 0")
    if args.compression_ratio <= 0:
        raise SystemExit("compression ratio must be greater than 0")

    total_reads = (args.coverage * args.genome_size) / args.read_length
    aligned_reads = total_reads * args.aligned_fraction
    sam_bytes = aligned_reads * args.sam_bytes_per_read
    bam_bytes = sam_bytes / args.compression_ratio
    index_bytes = bam_bytes * args.index_fraction
    overhead_bytes = bam_bytes * args.overhead_fraction
    total_bytes = bam_bytes + index_bytes + overhead_bytes

    print(f"Total reads at target coverage: {total_reads:,.0f}")
    print(f"Aligned reads: {aligned_reads:,.0f}")
    print(f"Uncompressed SAM estimate: {human_bytes(sam_bytes)}")
    print(f"Estimated BAM: {human_bytes(bam_bytes)}")
    print(f"Estimated index: {human_bytes(index_bytes)}")
    print(f"Working overhead: {human_bytes(overhead_bytes)}")
    print(f"Total storage to reserve: {human_bytes(total_bytes)}")

if __name__ == "__main__":
    main()

Run it with the example values:

python3 bam_size_estimate.py -g 3100000000 -c 30 -l 150 -f 0.95 -p 263.2 -r 3.5 -i 0.02 -o 0.10

Expected output:

Total reads at target coverage: 620,000,000
Aligned reads: 589,000,000
Uncompressed SAM estimate: 155.00 GB
Estimated BAM: 44.29 GB
Estimated index: 0.89 GB
Working overhead: 4.43 GB
Total storage to reserve: 49.60 GB

The script reports decimal units. Change human_bytes to use 1024 if your site reports GiB. The important part is consistency, not the label.

The options that matter most are -p and -r. A wrong P or R from a nonrepresentative pilot will dominate the error. -i and -o should come from your own pipeline. The defaults of zero are deliberate. They force you to decide whether index and overhead belong in the request.

Worked Example: 30x Human WGS BAM

This worked example uses stated assumptions, not universal constants. The point is the arithmetic and the sensitivity, not the exact number.

Inputs:

  • Reference size G = 3,100,000,000 bp.
  • Target coverage C = 30x.
  • Read length L = 150 bp.
  • Expected aligned fraction f = 0.95.
  • Pilot SAM bytes per aligned read P = 263.2.
  • Pilot compression ratio R = 3.5.
  • Index fraction i = 0.02.
  • Working overhead o = 0.10.

Step 1, total reads:

N = (30 × 3,100,000,000) / 150 = 620,000,000 reads

Step 2, aligned reads:

aligned = 620,000,000 × 0.95 = 589,000,000 reads

Step 3, uncompressed SAM bytes:

SAM bytes = 589,000,000 × 263.2 = 155,000,000,000 bytes

Step 4, BAM bytes:

BAM bytes = 155,000,000,000 / 3.5 = 44,285,714,286 bytes

Step 5, index and overhead:

index = 44,285,714,286 × 0.02 = 885,714,286 bytes
overhead = 44,285,714,286 × 0.10 = 4,428,571,429 bytes
total = 44,285,714,286 + 885,714,286 + 4,428,571,429 = 49,600,000,001 bytes

The reserve is about 49.6 GB. If you double coverage to 60x, the read count and BAM estimate roughly double, assuming P, R, and f stay the same. That assumption is often wrong. Higher coverage can change duplicate rates and tag content. Re-measure the pilot when the design changes.

If read length drops from 150 bp to 100 bp at the same coverage, the read count rises by 50 percent. The per-read record size also changes because sequence and quality strings are shorter. The net effect is not a simple linear scaling. Recompute with the new L and a pilot from the new read length.

If the aligned fraction falls from 0.95 to 0.80, the BAM estimate falls by about 16 percent. That is a large change for one parameter. Use a measured f from the same library and alignment method.

Bioinformatics File Formats That Affect the Estimate

The file formats around a BAM project change what you count. This matters when you compare FASTQ, FASTA, SAM, BAM, and CRAM in a storage request.

FormatContentTypical roleEffect on BAM estimate
FASTQReads plus per-base qualityRaw sequencing inputSupplies read count and quality distribution
FASTASequences without per-base qualityReference genome or protein setSupplies reference size and header complexity
SAMText alignmentsIntermediate and debuggingSupplies uncompressed bytes per read
BAMBinary compressed alignmentsPrimary alignment archiveThe target of the estimate
CRAMReference-based compressed alignmentsSpace-efficient archiveNeeds separate pilot and settings
BAIBAM indexRegion queriesAdd as a separate storage line

BAM and SAM are the paired formats in the alignment step. SAM is readable text. BAM is its binary compressed form. A BAM file usually includes the quality string, so a FASTQ with high quality-score entropy can produce a less compressible BAM. A FASTA reference does not have quality scores, so its size is not a proxy for BAM size.

FASTQ versus FASTA is a common source of confusion in storage estimates. FASTQ is a read file. FASTA is a sequence file. A FASTQ can be tens or hundreds of gigabytes while the reference FASTA is a few gigabytes. The BAM sits between them in role: it is a read file with alignment coordinates and usually with quality scores. If you estimate BAM size from FASTA size, you will be wrong by orders of magnitude.

CRAM deserves its own pilot. CRAM stores alignments relative to a reference and can compress better than BAM for some data. The savings depend on the reference, the read server, the lossy or lossless quality settings, and the downstream tools. Do not apply a BAM compression ratio to CRAM.

Common Mistakes and Limitations

Using the whole genome size for a targeted assay

A targeted panel covers a small fraction of the genome. If you plug the whole genome size into G, you overestimate reads and storage by the ratio of the genome to the target. Use the alignable target size for panel-specific estimates. Keep the full reference size for the BAM header and index if the aligner writes all contigs.

Confusing read pairs with reads

samtools view -c counts alignment records, not pairs. A paired-end BAM with 250 million pairs has 500 million records. The formula uses total reads. If you use pairs, you will underestimate by a factor of two.

The exact error message depends on the tool, but the symptom is a finished BAM close to half the estimate. Check the record count against 2 × pairs and confirm whether the aligner writes both mates as separate records.

Using a universal compression ratio

There is no single SAM-to-BAM compression ratio that fits all libraries. Quality-score entropy, duplicate rate, read-name redundancy, and optional tags all change the ratio. A pilot from a different organism or library prep can be off by a large margin. Measure R from the same data type.

Measuring bytes per read from a tiny or unusual pilot

A pilot with 1,000 reads is too small to represent read-name length, duplicate rate, and tag content. A pilot from a different aligner can have different CIGAR complexity. Use a pilot with at least tens of thousands of aligned reads and the same alignment settings. If the pilot is from a different read length, adjust the sequence and quality terms or rebuild the pilot.

Forgetting optional tags

Tags such as CB, UB, NM, MD, and AS add bytes. Single-cell BAMs can carry large barcode tags. UMI-aware pipelines can add several tags per read. A pilot from a non-single-cell library will underestimate a single-cell BAM. Measure the tag content directly with samtools view pilot.bam | head and inspect the optional fields.

Ignoring the BAM index

The BAI index is a separate file. It is usually smaller than the BAM, but it is not zero. For a large genome and deep coverage, the index can be hundreds of megabytes or more. Add it to the storage request. If the pipeline uses a CSI index for large references, measure that format instead.

Counting temporary files as free

Sorting and duplicate marking write temporary files. A pipeline that sorts a 44 GB BAM may need tens of GB of temporary space. The exact amount depends on the sort memory limit and the number of merge passes. Set -o from a test run or from your workflow's documented temporary-space behavior.

Mixing decimal and binary units

A file that is 44.3 GB is about 41.2 GiB. A storage request that mixes the two can be off by 7 percent. Use one unit system from start to finish. du -h often reports binary units, while cloud storage bills in decimal GB. Check the unit on both sides.

Forgetting the reference and archive copies

The BAM is not the whole project. The reference FASTA, .fai, .dict, BAM index, logs, and archive copies all occupy space. If the project keeps raw FASTQ, that is another large line. A storage plan that covers only the final BAM is incomplete.

Treating the estimate as a promise

The estimate is a model built from a pilot and a target design. It cannot predict library complexity, contamination, or a change in alignment settings. It also cannot predict the effect of a new aligner version. Use the estimate to reserve space and set alerts. Update it after the first full BAM exists.

Missing index errors

If samtools index cannot find the BAM, you may see:

[E::idx_find_and_load] Could not retrieve index file for 'pilot.bam'

Create the index with samtools index pilot.bam. If the BAM is truncated, you may see:

samtools view: error reading file "pilot.bam": truncated file

Rebuild the BAM from the SAM or re-download the file. A truncated BAM can still have a readable header, so a quick header check is not enough.

Missing reference index errors

If the FASTA index is missing or malformed, samtools faidx can fail with a format error. Rebuild the index from a valid FASTA. Check that the FASTA has consistent line lengths and that the first character is >. A malformed FASTA will produce a .fai that gives wrong lengths and a wrong G.

Python argument errors

If a required option is missing, argparse prints:

error: the following arguments are required: -g, -c, -l, -p, -r

Supply all required options. If a denominator is zero, Python raises:

ZeroDivisionError: float division by zero

Check that read length and compression ratio are greater than zero.

Large BAMs stress more than disk

SAM/BAM tools must manipulate large amounts of data, and memory management is a key challenge in that software class [1]. A storage estimate does not replace a memory plan. Sorting, duplicate marking, and local realignment can need RAM proportional to the sort window or the amplicon complexity. Plan memory separately.

How to Check the Estimate and What to Do Next

Check the estimate at three points: before alignment, after the first BAM, and after the final BAM. Before alignment, verify that G, C, L, f, P, and R come from the same design. After the first BAM, compare samtools view -c -F 4 to N × f. After the final BAM, compare du -h to the estimate and inspect the difference.

A useful check is to compute the implied bytes per aligned read from the finished BAM:

BAM bytes / aligned reads = compressed bytes per aligned read

Compare that to P / R from the pilot. If the finished value is much higher, look for longer read names, extra tags, a lower compression level, or a higher duplicate rate. If it is much lower, check for additional filtering or a different compression setting.

If the estimate is too large for the available storage, consider these options:

  • Reduce coverage only if the experimental question allows it.
  • Trim adapters and low-quality bases before alignment.
  • Remove unnecessary optional tags before the final BAM.
  • Use a higher compression level if the pipeline supports it.
  • Use CRAM for archival storage after checking downstream tool support.
  • Split the project by chromosome, lane, or cohort and process in batches.
  • Keep raw FASTQ in compressed archive storage and keep only the final BAM on fast storage.
  • Set temporary-directory space explicitly in the workflow.

If the estimate is too small, reserve a larger margin and recheck the pilot. A pilot from a different read length, a different aligner, or a different tag set is the usual cause. The fix is a new pilot, not a bigger guess.

Frequently Asked Questions

What is a BAM file size calculator estimate?

A BAM file size calculator estimate is a projection of the disk space an alignment file will need, built from reference size, coverage, read length, alignment rate, and a pilot measurement of bytes per read and compression. It is a planning number, not a guarantee.

What is the BAM file size calculator estimate formula?

The practical formula is S_bam = (N × f × P) / R, where N is total reads, f is the aligned fraction, P is uncompressed SAM bytes per aligned read, and R is the SAM-to-BAM compression ratio. Add the index and working overhead separately.

How do I calculate BAM file size from coverage and read length?

Compute total reads as (coverage × reference size) / read length, multiply by the aligned fraction, multiply by measured SAM bytes per read, and divide by the measured compression ratio. For paired-end data, use total reads, not pairs.

Can I estimate BAM size from FASTQ size?

You can use FASTQ size as a rough input only after measuring the relationship on a pilot from the same library. FASTQ and BAM have different redundancy and quality encoding, so a direct ratio is unreliable.

Why is my BAM larger than the estimate?

Common causes are a higher duplicate rate, longer read names, extra optional tags, lower compression, more CIGAR operations, or a pilot that did not represent the full library. Re-measure P and R from a representative BAM.

Does samtools view -c count read pairs or reads?

samtools view -c counts alignment records, not pairs. A paired-end BAM with both mates stored has two records per pair. Use the record count for the BAM formula and divide by two only when you need the pair count.

Should I use BAM or CRAM for storage?

BAM is widely supported and easy to use for interactive analysis. CRAM can reduce size for archival storage, but it needs a reference and tool support. Estimate CRAM with its own pilot rather than applying a BAM ratio.

What is the difference between FASTQ and FASTA for BAM estimation?

FASTQ stores reads with per-base quality scores and supplies the read count and quality distribution. FASTA stores sequences without per-base quality and usually supplies the reference size. They are different inputs and cannot be substituted for each other.

Sources

  1. Comparing Ease of Programming in C++, Go, and Java for Implementing a Next-Generation Sequencing Tool.