All protocols

Quantify transcript expression with Salmon

Build a Salmon transcriptome index and quantify paired-end RNA-seq reads alignment-free, with automatic library-type detection.

SSSudipta SardarUpdated July 21, 2026

Prerequisites

  • Salmon installed (`salmon` on your PATH)
  • A transcriptome FASTA file
  • Paired-end RNA-seq FASTQ files (R1 and R2)

1Build the transcriptome index

Index your transcriptome FASTA once and reuse it for every sample. A k-mer length of 31 is the default and works well for reads 75 bp and longer; drop it for shorter reads. Salmon writes the index to salmon_index/.

bash
salmon index -t transcripts.fasta -i salmon_index -k 31

Expected output

Version Info: This is the most recent version of salmon.
index ["salmon_index"] did not previously exist  . . . creating it
[2026-07-21 07:30:12.345] [jointLog] [info] building index
[2026-07-21 07:30:12.508] [puff::index::jointLog] [info] Replaced 128 duplicate sequences.
[2026-07-21 07:30:12.512] [puff::index::jointLog] [info] Clipped poly-A tails from 9 transcripts
[2026-07-21 07:30:41.902] [puff::index::jointLog] [info] Building rank-select dictionary and saving to disk
[2026-07-21 07:30:42.310] [puff::index::jointLog] [info] Writing sequence data to file . . .
[2026-07-21 07:33:05.123] [puff::index::jointLog] [info] wrote 214081 contigs
[2026-07-21 07:33:05.640] [puff::index::jointLog] [info] finished index construction; index written to salmon_index/

2Quantify the paired reads

Point Salmon at the index and both read mates. `-l A` auto-detects the library type, `-p 8` uses eight threads, and `--validateMappings` turns on selective alignment for more accurate assignment. Estimates land in quant_out/.

bash
salmon quant -i salmon_index -l A -1 R1.fastq.gz -2 R2.fastq.gz -p 8 --validateMappings -o quant_out

Expected output

Version Info: This is the most recent version of salmon.
### salmon (selective-alignment-based) v1.10.0
### [ program call was ]: salmon quant -i salmon_index -l A -1 R1.fastq.gz -2 R2.fastq.gz -p 8 --validateMappings -o quant_out
Logs will be written to quant_out/logs
[2026-07-21 07:35:01.234] [jointLog] [info] setting maxHashResizeThreads to 8
[2026-07-21 07:35:01.235] [jointLog] [info] Usage of --validateMappings implies use of minScoreFraction. Since not explicitly specified, it is being set to 0.65
[2026-07-21 07:35:01.500] [jointLog] [info] parsing read library format
[2026-07-21 07:35:02.100] [jointLog] [info] Automatically detected most likely library type as ISR
processed 24,500,000 fragments
[2026-07-21 07:36:45.001] [jointLog] [info] Mapping rate = 92.4103%
[2026-07-21 07:36:45.120] [jointLog] [info] finished quantifyLibrary()
[2026-07-21 07:36:46.004] [jointLog] [info] writing output

3Inspect the quantification table

Per-transcript estimates live in quant_out/quant.sf. Peek at the header and first row to confirm the TPM and NumReads columns are populated before loading them into tximport or DESeq2.

bash
head -2 quant_out/quant.sf

Expected output

Name	Length	EffectiveLength	TPM	NumReads
ENST00000456328.2	1657	1483.000	3.821042	112.000

Troubleshooting

Mapping rate is unexpectedly low (e.g. below 70%)

Build a decoy-aware index: concatenate the genome FASTA after the transcripts as a decoy, list the genome sequence names in decoys.txt, and pass `-d decoys.txt` to `salmon index`. This stops reads from unannotated regions being misassigned to transcripts.

You are unsure of the library strandedness

Keep `-l A` and let Salmon auto-detect it. The inferred type is reported in the log (e.g. `Automatically detected most likely library type as ISR`), so you can read it back and hard-code it later if you prefer.