RNA Counts (TPM / CPM)
The units RNA-seq expression is reported in: raw fragment counts per gene, and the normalized forms (CPM, TPM) that adjust for sequencing depth and, for TPM, transcript length.
RNA counts are the per-gene or per-transcript numbers an RNA-seq quantifier produces, and TPM and CPM are two different normalizations of those numbers: CPM divides by library size only, TPM divides by transcript length first and then by library size. The order matters, and it is the whole difference.
How it works
Start with what the instrument gives you: reads that align to the transcriptome. A quantifier (salmon, kallisto, RSEM, featureCounts) assigns each read or fragment to a gene or transcript. The output is a count, often fractional if the tool does probabilistic assignment across isoforms.
Raw counts are not comparable across samples because libraries differ in depth. One sample gets 28M reads, another 41M. CPM fixes exactly that:
CPM_g = count_g / (total_counts / 1e6)
Nothing else. CPM says “if this library had been sequenced to 1M reads, this gene would have gotten this many.” It does not correct for the fact that a 12 kb transcript catches more fragments than a 900 bp transcript at equal molar concentration. For comparing one gene across samples, that is fine, since transcript length is constant. For comparing two genes inside one sample, it is not.
TPM corrects length first:
rate_g = count_g / effective_length_g
TPM_g = rate_g / sum(all rates) * 1e6
Effective length, not raw length: salmon and RSEM subtract the expected fragment length distribution, so a 300 bp transcript in a library with 200 bp mean fragments has an effective length closer to 100. Ignore this and short transcripts are systematically wrong.
The consequence people quote: TPM columns sum to exactly 1e6 in every sample. So do CPM columns. The difference is what a single value means. A TPM of 40 means 40 out of every million transcript molecules in that sample are this gene. A CPM of 40 means 40 out of every million sequenced fragments came from this gene. TPM is a molar fraction. CPM is a read fraction.
RPKM and FPKM do the same two operations in the opposite order (depth first, then length), which is why their columns do not sum to a constant and why cross-sample comparison of RPKM is unreliable.
In your own data
Expect a quant.sf per sample from salmon: Name, Length, EffectiveLength, TPM, NumReads. NumReads is the fractional estimated count. Aggregate transcripts to genes with tximport in R, and use countsFromAbundance="lengthScaledTPM" when you want gene-level counts that carry the length correction into a counts matrix. Do not sum transcript TPMs and then hand the result to DESeq2 as if it were counts.
The rule we follow:
- Differential expression between samples: raw counts into DESeq2 or edgeR. Both fit negative binomial models on integers and estimate their own size factors (median-of-ratios, TMM). Handing them TPM destroys the mean-variance relationship they depend on.
- Ranking genes within one sample, or any comparison across genes of different length: TPM.
- Filtering, quick QC, coexpression input: CPM, often as
log2(CPM + 1)or edgeR’scpm(y, log=TRUE, prior.count=2).
For coexpression networks specifically, the choice of normalization and transformation changes the network more than most people expect, and within-sample normalization plus a log transform is a reasonable default 1. The same sensitivity shows up downstream: normalization choice materially shifts which genes appear differentially expressed, and taking the intersection of several methods is a defensible way to get a stable gene list 2. When those expression values are projected onto a protein interaction network, the normalization method again changes which modules come out 3.
Common mistakes we see in real files:
- Filtering on raw counts. Use
rowSums(cpm(y) > 1) >= nwhere n is your smallest group size, so a shallow library does not drop genes. - Whole blood samples with 50-70% of reads in HBB, HBA1, HBA2. Globin crowds out everything else and deflates every other gene’s TPM. Globin depletion during library prep recovers a substantial number of detectable transcripts in whole blood 4. Check your globin fraction before interpreting anything.
- Comparing TPM across quantifiers or annotation versions. The denominator is the sum over all transcripts in your index. Change the index, change every TPM. Pipeline choice alone produces meaningfully different quantitative results 5.
- Treating low TPM as absence. lncRNAs and many regulatory transcripts sit near zero in bulk and are diluted by cell type mixing 6.
Limitations
TPM’s fixed sum makes it compositional. If one gene goes from 5% to 30% of your transcriptome, every other TPM drops even with no change in absolute molecules. Neither TPM nor CPM measures molecules per cell.
Length correction depends on knowing which isoform produced each read, and short-read assignment across overlapping isoforms is uncertain. Long-read quantification reduces that ambiguity but brings its own bias model 7, and transcript structure is more varied than most annotations admit 8.
Finally, normalization does not remove batch effects. Samples processed on different days will separate no matter what units you use, and you need explicit correction plus a metric to check it worked 9. Any interpretation of what a shift in your expression profile means for your health requires a clinician.
Woolf Software builds longitudinal molecular profiles of individuals: whole-genome sequencing, RNA sequencing, proteomics, blood biomarkers, and continuous glucose data, integrated into one model of you. Build your profile.
Your quantifier writes a counts matrix and a TPM column; which one you feed to which tool determines whether your results are real or an artifact of library size.
Related Terms
References
- Kayla A. Johnson, Arjun Krishnan. Robust normalization and transformation techniques for constructing gene coexpression networks from RNA-seq data . Genome Biology, 2022. DOI
- Mohammad Elahimanesh, Mohammad Najafi. Differentially expressed genes of RNA-seq data are suggested on the intersections of normalization techniques . Biochemistry and Biophysics Reports, 2024. DOI
- Elif Düz, Tunahan Çakır. Effect of RNA-Seq data normalization on protein interactome mapping for Alzheimer’s disease . Computational Biology and Chemistry, 2024. DOI
- Christina A. Harrington, Suzanne S. Fei, Jessica Minnier, et al.. RNA-Seq of human whole blood: Evaluation of globin RNA depletion on Ribo-Zero library method . Scientific Reports, 2020. DOI
- Luis A. Corchete, Elizabeta A. Rojas, Diego Alonso-López, et al.. Systematic comparison and assessment of RNA-seq procedures for gene expression quantitative analysis . Scientific Reports, 2020. DOI
- Siyuan John Liu, Tomasz J. Nowakowski, Alex A. Pollen, et al.. Single-cell analysis of long non-coding RNAs in the developing human neocortex . Genome Biology, 2016. DOI
- Ying Chen, Andre Sim, Yuk Kei Wan, et al.. Context-aware transcript quantification from long-read RNA-seq data with Bambu . Nature Methods, 2023. DOI
- Fairlie Reese, Brian Williams, Gabriela Balderrama-Gutierrez, et al.. The ENCODE4 long-read RNA-seq collection reveals distinct classes of transcript structure diversity . 2023. DOI
- Maren Büttner, Zhichao Miao, F. Alexander Wolf, et al.. A test metric for assessing single-cell RNA-seq batch correction . Nature Methods, 2018. DOI