# Cell proliferation and doubling time: fitting the growth phase and comparing cell lines

> Estimate doubling time from the slope of log cell number over the exponential phase, before cells approach confluence. Compare cell lines on growth rates from independent experiments, not on wells at one time point. Python and R code.

Canonical: https://www.licklider.ai/guides/cell-doubling-time/
Section: Guides › Repeated measurements over time
Author: Licklider · Published 2026-11-11 · Last reviewed 2026-11-11 (UTC)

> **Quick answer.** Count cells (or use a measure proportional to cell number) at several times, take natural logs, and fit a straight line over the **exponential phase**, while cells are still sparse: the slope is the growth rate, and the **doubling time is ln 2 divided by the slope**. Points near confluence, where growth slows, make the doubling time too long. To compare cell lines or treatments, estimate one growth rate per **independent experiment** (averaging the wells first) and compare those, with a paired t-test across experiments when both lines were run in every experiment (Welch's t-test on the per-experiment rates otherwise). Wells from one experiment are technical replicates; a t-test on wells at a single time point gave a false positive in 27.3% of our simulated studies with no real difference.

**Terms used below.** *Exponential phase*: the period when cells divide at a constant rate, so log cell number rises in a straight line. *Growth rate*: the slope of natural-log cell number against time, per hour. *Doubling time*: the time for the number of cells to double, ln 2 ÷ growth rate (0.693 ÷ rate). *Lag phase*: the slower start after seeding. *Confluence*: the state in which cells cover the available surface and growth slows and stops. *Independent experiment*: a separate seeding on a different day or passage, the unit that varies by chance from one run to the next. *Technical replicate*: a repeat well within one experiment. *Paired t-test*: compares two lines within each experiment and tests the average difference. *95% confidence interval (CI)*: the range of effects compatible with the data. *False positive*: a "significant" result when there is no real effect. *Natural log*: logarithm to base e (ln). *Logistic growth*: growth that starts exponentially and levels off at confluence. *Welch's t-test*: compares two independent groups without assuming equal spread. *Power*: the chance of detecting an effect that is really there. *Passage*: one cycle of splitting cells into a new vessel. *GR (growth-rate inhibition) metrics*: drug-response measures based on growth rates rather than end-point counts. *IC50 and Emax*: the drug concentration giving half the maximal effect, and the maximal effect. *MTT*: a colour-change assay of cell metabolism. *Holm adjustment*: a correction for several comparisons against one control that keeps the overall false-positive rate at 5%. *Plateau*: the flat part of the curve at confluence. *Subsamples*: repeat measurements within one experiment, such as wells. *Random seed*: the starting number for the simulated data.

## Which analysis for your question

| Question | Analysis | Report |
| --- | --- | --- |
| How fast does a line grow? | Slope of log cell number over the exponential phase, per experiment | Doubling time (mean over experiments) and the range |
| Does a knockout or treatment change growth? | Growth rates per experiment, compared between lines (paired by experiment if both lines are in every experiment; with three or more lines, each against control with a Holm adjustment) | Difference in growth rate with 95% CI; doubling times |
| Does a drug reduce growth? | Growth-rate-based measures rather than counts at one time | GR metrics (Hafner et al. 2016; the online GRcalculator or the GRmetrics R package), which need cell counts at the time of treatment and at the end, for treated and untreated wells |
| How many cells are there at 96 h? | Counts per well, averaged per experiment | Mean per experiment, n = experiments |

Sherley and colleagues note that "the application of the exponential growth equation is the standard method employed in the quantitative analyses of mammalian cell proliferation in culture" ([Sherley et al. 1995](https://doi.org/10.1111/j.1365-2184.1995.tb00062.x)). The ATCC culture guide warns that "the calculated doubling time may be a composite of growth during more than one of these phases" of the growth cycle, and that growth during the exponential phase "is fairly constant and reproducible" ([ATCC](https://www.atcc.org/resources/culture-guides/animal-cell-culture-guide/)). For drug responses, Hafner and colleagues showed that IC50 and Emax "are highly sensitive to the number of divisions taking place over the course of a response assay" ([Hafner et al. 2016](https://doi.org/10.1038/nmeth.3853)). On what counts as n, Lazic and colleagues write that multiple wells on each day "are then treated as subsamples and do not contribute to N" ([Lazic et al. 2018](https://doi.org/10.1371/journal.pbio.2005282)).

## Worked example: wild-type and knockout, 3 experiments

Constructed data: cell counts at 0, 24, 48, 72 and 96 h for a wild-type (WT) and a knockout (KO) line, 3 wells each, in 3 independent experiments. By construction growth is logistic, with early rates of 0.035 per hour for WT (doubling time 19.8 h) and 0.030 per hour for KO (doubling time 23.1 h), slowing as wells approach confluence. The random seed was the first one tried and was not chosen for its result. Stored code and data: [counts.csv](/guides/cell-doubling-time/counts.csv), [model.py](/guides/cell-doubling-time/model.py) (the growth model), [make_data.py](/guides/cell-doubling-time/make_data.py), [analysis.py](/guides/cell-doubling-time/analysis.py), [analysis.R](/guides/cell-doubling-time/analysis.R) and [the analysis output](/guides/cell-doubling-time/analysis_output.txt); analysis.py and analysis.R print the same output.

| Experiment | WT doubling time, fit 0–72 h (with 96 h) | KO doubling time, fit 0–72 h (with 96 h) |
| --- | --- | --- |
| 1 | 21.5 h (22.8 h) | 25.5 h (26.6 h) |
| 2 | 23.3 h (24.7 h) | 24.3 h (25.9 h) |
| 3 | 22.4 h (23.4 h) | 22.8 h (24.4 h) |

| Comparison | Result |
| --- | --- |
| Doubling time from the mean growth rate (range over experiments) | WT 22.4 h (21.5 to 23.3); KO 24.1 h (22.8 to 25.5) |
| **KO − WT growth rate, paired over 3 experiments** | **−0.0022 per hour (95% CI −0.0081 to 0.0036), p = 0.24** |
| Welch's t-test on 96-h counts, 9 wells per line as n | p = 0.000076 |

The knockout grew a little more slowly in every experiment, but with three experiments the interval for the difference includes zero; the wells-as-n test at 96 h makes the same data look decisive. Almost every doubling time is also longer than the true 19.8 and 23.1 h (the exception, KO in experiment 3, is chance): even by 72 h, growth had begun to slow as cells approached confluence, and adding the 96-h point lengthens it further. In 10,000 simulated studies of this design ([simulation.py](/guides/cell-doubling-time/simulation.py), [the simulation output](/guides/cell-doubling-time/simulation_output.txt)):

| Scenario | Paired test on experiment growth rates | Welch's t-test on 96-h counts, wells as n |
| --- | --- | --- |
| No difference (false positives) | 4.8% | **27.3%** |
| KO slower, 0.030 vs 0.035 per hour (power) | 20.5% | 79.0% (not comparable: this test's false-positive rate is 27.3%) |

Across the simulated studies, fitting WT up to 48 h gave a median doubling time of 21.1 h, up to 72 h 22.0 h and up to 96 h 23.4 h, against a true 19.8 h. With three experiments, the correct test has little power for this difference: in the same simulation model, about 9 independent experiments would give 80% power (8 would give 77%; [power.py](/guides/cell-doubling-time/power.py), [output](/guides/cell-doubling-time/power_output.txt)). Plan more independent experiments rather than more wells. And one wild-type and one knockout clone show only that these two clones differ; to attribute a difference to the knockout, compare several independent clones, as Lazic and colleagues point out for cell lines.

```python
# Condensed: analysis.py also prints each experiment's doubling time and the wells-as-n comparison
import numpy as np, pandas as pd
from scipy import stats

d = pd.read_csv("counts.csv")                        # one row per well per time: experiment, line, well, hour, cells
d["logc"] = np.log(d.cells)
g = d[d.hour <= 72].groupby(["experiment", "line", "hour"]).logc.mean().reset_index()   # exponential phase; wells averaged
r = g.groupby(["experiment", "line"]).apply(lambda x: np.polyfit(x.hour, x.logc, 1)[0], include_groups=False).unstack()
print(np.log(2) / r.mean())                          # mean doubling time per line, hours
diff = r.KO - r.WT; print(stats.ttest_rel(r.KO, r.WT))   # n = 3 independent experiments
print(diff.mean() + np.array([-1, 1]) * stats.t.ppf(0.975, len(diff) - 1) * diff.std(ddof=1) / np.sqrt(len(diff)))   # 95% CI
```

```r
d <- read.csv("counts.csv"); d$logc <- log(d$cells)
g <- aggregate(logc ~ experiment + line + hour, data = d[d$hour <= 72, ], mean)
r <- sapply(split(g, list(g$experiment, g$line)), function(x) coef(lm(logc ~ hour, data = x))[2])
r <- matrix(r, nrow = 3, dimnames = list(1:3, c("KO", "WT")))   # rows: experiments
log(2) / colMeans(r)                                 # doubling time per line
t.test(r[, "KO"], r[, "WT"], paired = TRUE)
```

## Before you analyse

1. **Seed low enough** that cells stay well below confluence for the whole window you fit, count often early on, and plot log cell number against time to see where the line bends at both ends (lag phase at the start, confluence at the end).
2. **Choose the fitting window in advance** (start after any lag, stop well before confluence) and apply it to every line. Even early windows lengthened the doubling time here: fitting to 48 h (about an eighth of confluent density) gave 21.1 h and fitting to 72 h (about a quarter) 22.0 h, against a true 19.8 h. A practical rule is to stop while cells are below about a tenth of the confluent density, or to check that the last point still lies on the straight line through the earlier ones; earlier and more frequent counts give a truer rate. Fix or drop wells with zero counts before taking logs.
3. **Average wells within each experiment** (on the log scale) and use one growth rate per experiment and line ([what counts as n](/guides/what-counts-as-n/)).
4. **Know what your assay measures.** Riss and colleagues note that "MTT reduction is a marker reflecting viable cell metabolism and not specifically cell proliferation" ([Riss et al., Assay Guidance Manual](https://www.ncbi.nlm.nih.gov/books/NBK144065/)); plate a dilution series of counted cells, check that the signal rises in proportion over your working range, or count cells.
5. **For drugs, separate growth from killing**: compare growth rates, or use GR metrics, rather than counts at one time point.

## Check what an AI assistant ran

1. **The assistant compared counts at one time point with wells as n.** Ask for one growth rate per independent experiment.
2. **The assistant fitted all time points, including the plateau.** Ask for the fit restricted to the exponential phase.
3. **The assistant used log base 10 with ln 2** (or the reverse). The doubling time is ln 2 divided by the slope of natural-log counts (or log₁₀ 2 divided by the slope of log₁₀ counts).
4. **The assistant treated an MTT signal as cell number** without checking proportionality.

## Report it

> Cells were counted at 0, 24, 48, 72 and 96 h in [3] wells per line in [3] independent experiments. Growth rates were estimated per experiment as the slope of the natural-log cell number (mean of wells) against time over the exponential phase (0–[72] h, decided in advance), and doubling time as ln 2 divided by the growth rate. Lines were compared with a paired t-test on the per-experiment growth rates, as both lines were run in every experiment (R 4.3.3).

> Doubling time was [22.4] h for WT (range [21.5] to [23.3] h over experiments) and [24.1] h for KO ([22.8] to [25.5] h); the difference in growth rate was [−0.0022] per hour (95% CI [−0.0081] to [0.0036]; p = [0.24]; n = [3] experiments).

Replace the bracketed values with your own.

## References

- Sherley JL, Stadler PB, Stadler JS (1995). A quantitative method for the analysis of mammalian cell proliferation in culture in terms of dividing and non-dividing cells. *Cell Proliferation* 28:137–144. [doi:10.1111/j.1365-2184.1995.tb00062.x](https://doi.org/10.1111/j.1365-2184.1995.tb00062.x)
- ATCC. Animal Cell Culture Guide. [atcc.org](https://www.atcc.org/resources/culture-guides/animal-cell-culture-guide/) (checked 11 November 2026)
- Hafner M, Niepel M, Chung M, Sorger PK (2016). Growth rate inhibition metrics correct for confounders in measuring sensitivity to cancer drugs. *Nature Methods* 13:521–527. [doi:10.1038/nmeth.3853](https://doi.org/10.1038/nmeth.3853)
- Lazic SE, Clarke-Williams CJ, Munafò MR (2018). What exactly is 'N' in cell culture and animal experiments? *PLOS Biology* 16:e2005282. [doi:10.1371/journal.pbio.2005282](https://doi.org/10.1371/journal.pbio.2005282)
- Riss TL, Moravec RA, Niles AL, et al. Cell viability assays. In: *Assay Guidance Manual*. NCBI Bookshelf. [ncbi.nlm.nih.gov/books/NBK144065](https://www.ncbi.nlm.nih.gov/books/NBK144065/) (checked 11 November 2026)

## Related

- [Tumour growth curves](https://www.licklider.ai/guides/tumour-growth-curves/)
- [What counts as n](https://www.licklider.ai/guides/what-counts-as-n/)
- [SuperPlots](https://www.licklider.ai/guides/superplots/)
- [Comparing IC50 values](https://www.licklider.ai/guides/compare-ic50-dose-response-curves/)
- [Seahorse respiration analysis](https://www.licklider.ai/guides/seahorse-respiration-analysis/)
- [Scratch wound-healing assay](https://www.licklider.ai/guides/scratch-wound-healing-assay/)

## How this page was made

- Written and published by Licklider. Recommendations cite peer-reviewed methods papers and culture guidance listed under References; cited passages were checked against the source text.
- The worked example uses constructed data. Its numbers were produced by stored code (Python 3.13 with SciPy 1.18.1; R 4.3.3, base R), and the two languages print identical output; the simulation was run in Python.
- Separate review passes checked the statistics, the citations and readability before publication.
