Blog Analyze your data
Back to Blog

How to Analyze qPCR Data When Your Housekeeping Genes Aren't Stable

If your reference gene Ct values shift by more than ~0.5 cycles between experimental groups, your ΔΔCt results are compromised — full stop. Every unit of drift in your normalizer directly transfers into your fold-change calculation, and there is no downstream math that fixes a bad reference. The first thing to do is confirm the variation is real (not a loading or pipetting artifact), then decide whether to switch references, use multiple references, or adopt an approach that accounts for unequal normalizer expression.

Here's the uncomfortable truth: housekeeping gene instability is not an edge case. GAPDH gets upregulated under hypoxia. ACTB shifts with cell density and mechanical stress. B2M changes with interferon signaling. 18S rRNA is transcribed by RNA Pol I and doesn't behave like your mRNA targets when you use oligo-dT priming. If you're comparing tissues, treatment conditions, or disease vs. healthy samples, at least one of the "classic" references is probably moving. The question is what to do about it.

First, Quantify the Problem

Before you change your analysis strategy, figure out how much your reference gene is actually varying. Pull the raw Ct values for your normalizer across all groups and look at two things:

  1. The spread across biological replicates within a group. Technical replicate SD should be <0.3 Ct; biological replicate SD is typically 0.5–1.0 Ct for well-controlled experiments. If your within-group variation is larger than your between-group variation, the "instability" might just be noise.

  2. The difference in group means. If your control group averages Ct 18.2 for GAPDH and your treated group averages Ct 19.8, that's a 1.6 Ct shift — roughly a 3-fold difference in expression. That will directly distort every ΔCt you calculate.

Run a simple t-test (or ANOVA for multiple groups) on the raw Ct values of your reference gene. If p < 0.05, your normalizer is significantly different across conditions and you cannot use it alone for ΔΔCt. Even if p > 0.05, a mean shift of >0.5 Ct should make you cautious, especially with small sample sizes where you're underpowered to detect real differences.

A quick gut check: calculate ΔΔCt for your reference gene against itself. It should be 0 by definition within a group, but look at the between-group values. If your reference gene would show a "fold change" of 1.5 or more when compared across conditions, it's contributing meaningful error.

Not sure your reference genes are stable? VoilaPCR Plus runs geNorm on your validation plate — M values, a stability ranking, and how many reference genes you actually need — straight from your uploaded Ct data. No Excel, no R.

Run geNorm on my data →

Strategy 1: Find a Better Reference Gene

The most straightforward fix is to use a different reference that is actually stable in your system. This sounds obvious, but many labs inherit a reference gene from whoever set up the assay five years ago without validating it for current conditions.

Good candidates to test (if you haven't):

The key is to test 4–6 candidates across your specific experimental conditions and rank them by stability. This is exactly what algorithms like geNorm (Vandesompele et al., 2002) and NormFinder (Andersen et al., 2004) were designed to do.

geNorm calculates a pairwise variation metric (M value) for each candidate gene across your samples. Lower M = more stable. The recommended threshold is M < 0.5 for homogeneous samples (same tissue/cell type) and M < 1.0 for heterogeneous panels. It also tells you how many reference genes you need via the V (pairwise variation) metric — if V₂/₃ < 0.15, two references are sufficient.

NormFinder takes a slightly different approach by explicitly modeling inter-group and intra-group variation, which makes it better suited when you have defined experimental groups (e.g., treated vs. control). It can recommend the best single gene or the best combination of two.

Run both. If they agree on the top-ranked gene, you're in good shape. If they disagree, use the combination of two genes that both algorithms rank highly.

Strategy 2: Normalize to Multiple Reference Genes

This is the gold standard recommended by the MIQE guidelines (Bustin et al., 2009), and it's what you should be doing routinely if your experiments involve comparisons across tissues, developmental stages, or treatments that affect core metabolism.

The approach:

  1. Select 2–3 validated stable reference genes (using geNorm/NormFinder as above).
  2. For each sample, calculate the geometric mean of their Ct values (not the arithmetic mean — geometric mean handles genes with different expression levels more appropriately).
  3. Use this geometric mean as your normalization factor in place of a single reference gene Ct.

Worked example: Suppose for Sample A, you measure HPRT1 Ct = 24.5, TBP Ct = 29.2, and PPIA Ct = 22.8. The geometric mean is:

(24.5 × 29.2 × 22.8)^(1/3) = (16,313.28)^(1/3) ≈ 25.37

Your ΔCt for that sample becomes: Ct(GOI) − 25.37.

Why the geometric mean and not the arithmetic mean? Because Ct values are on a log₂ scale. A gene expressed at Ct 20 vs. Ct 30 differs by ~1000-fold in abundance. The arithmetic mean would be disproportionately influenced by the lower-expressed gene. The geometric mean better represents a central tendency on a logarithmic scale.

In practice, for genes with similar Ct values (within 2–3 cycles of each other), the arithmetic and geometric means are nearly identical. The distinction matters more when you're combining a high-abundance reference like 18S (Ct ~10–12) with moderate-abundance ones like TBP (Ct ~28–30) — which, by the way, is a combination you should probably avoid.

Strategy 3: Pfaffl Method with Efficiency Correction

If your reference gene varies and your primer efficiencies aren't ideal (outside the 90–110% range), the standard ΔΔCt method (Livak and Schmittgen, 2001) breaks down on two fronts. The Pfaffl method (Pfaffl, 2001) accommodates different amplification efficiencies for target and reference genes:

Ratio = (E_target)^ΔCt_target(control−sample) / (E_ref)^ΔCt_ref(control−sample)

Where E is the amplification efficiency (2.0 for 100% efficiency). This doesn't solve reference gene instability per se — if ΔCt_ref varies systematically across groups, you still have a problem. But it's worth using when you combine an imperfect reference with imperfect efficiencies, because at least one source of error is corrected.

Strategy 4: Use Total RNA Input as Your Normalizer

If you've tested multiple candidate references and nothing is stable — which can happen when comparing very different tissues or extreme treatment conditions — consider bypassing gene-based normalization entirely.

The approach: normalize your Ct values to total RNA input mass. If every sample was reverse-transcribed from exactly 500 ng of intact total RNA (quantified carefully by fluorometric assay like Qubit, not NanoDrop A260), you can report your GOI expression per unit of total RNA input. Your ΔCt is simply:

ΔCt = Ct(GOI) − log₂(RNA input in ng × some constant)

Or more practically, just report 2^(−Ct) scaled to your RNA input and compare across groups.

This is less precise than a well-validated reference gene because it doesn't control for reverse transcription efficiency, but it's more honest than normalizing to a reference that's actively changing. It's particularly useful as a sanity check — if your results look the same with total RNA normalization as they do with your best reference gene, that's reassuring.

What Not to Do

A few things I see regularly that make the problem worse:

The Practical Takeaway

Every qPCR experiment should include at least a quick stability check on its reference genes — plot the Ct values by group, run basic stats, and confirm the assumption of stable expression before calculating any ΔΔCt. If you're starting a new project, spend one plate running 5–6 candidate references across your conditions and let geNorm or NormFinder pick the best pair. It takes half a day and saves months of unreliable data.

If you're staring at a dataset where the reference gene has already drifted and you can't re-run, VoilaPCR flags reference gene instability automatically during analysis and shows you exactly how much the normalizer Ct varies across your groups — so you can make an informed call before those fold changes end up in a figure.

Not sure your reference genes are stable? VoilaPCR Plus runs geNorm on your validation plate — M values, a stability ranking, and how many reference genes you actually need — straight from your uploaded Ct data. No Excel, no R.

Run geNorm on my data →