Exponential and Logistic Growth

Every population, from a bacterial colony to an outbreak’s infected class, starts by growing in proportion to its own size. Exponential and logistic growth are the two baseline models that describe this — the first for unlimited resources, the second for the density dependence that eventually reins growth in.

Exponential growth rises without bound while logistic growth levels off at the carrying capacity K.

Exponential growth

When each individual reproduces at a constant per-capita rate and nothing limits them, the population NN obeys dNdt=rN,\frac{dN}{dt}=rN, where rr is the intrinsic growth rate (births minus deaths per individual per unit time). This is the simplest ordinary differential equation in ecology: the rate of change is proportional to the current size. Separating variables and integrating gives the closed-form solution N(t)=N0ert,N(t)=N_0\,e^{rt}, where N0=N(0)N_0=N(0) is the initial size. Deriving this solution is a standard application of integration and the exponential function.

When r>0r>0 the population grows without bound; when r<0r<0 it decays toward zero; when r=0r=0 it stays put.

Doubling time

A useful summary of exponential growth is the doubling time t2t_2, the time for the population to double. Setting N(t2)=2N0N(t_2)=2N_0 gives ert2=2e^{rt_2}=2, so t2=ln2r0.693r.t_2=\frac{\ln 2}{r}\approx\frac{0.693}{r}. The same ln2/r\ln 2/r formula (with rr the epidemic growth rate) gives the early doubling time of cases in an outbreak.

Logistic growth

Unlimited growth is unrealistic: crowding reduces per-capita reproduction as resources run short. The logistic model makes the per-capita rate decline linearly with density, dNdt=rN(1NK),\frac{dN}{dt}=rN\left(1-\frac{N}{K}\right), where KK is the carrying capacity — the population size the environment can sustain. When NN is small the bracket is near 11 and growth is nearly exponential; as NKN\to K the bracket goes to 00 and growth stops.

The solution is the sigmoid (S-shaped) curve N(t)=K1+(KN0N0)ert.N(t)=\frac{K}{1+\left(\dfrac{K-N_0}{N_0}\right)e^{-rt}}. It rises slowly at first, accelerates, then levels off at KK.

Where growth is fastest

The absolute growth rate dN/dtdN/dt is a downward parabola in NN, maximized where its derivative with respect to NN vanishes: r(12N/K)=0r(1-2N/K)=0, i.e. at N=K2.N=\frac{K}{2}. At the inflection point N=K/2N=K/2 the population is adding individuals fastest, at rate rK/4rK/4.

Equilibria and stability

Setting dN/dt=0dN/dt=0 gives two equilibria: N=0N^*=0 and N=KN^*=K. Linearizing f(N)=rN(1N/K)f(N)=rN(1-N/K) gives f(N)=r(12N/K)f'(N)=r(1-2N/K). At N=0N^*=0, f(0)=r>0f'(0)=r>0, so the origin is unstable — a few individuals grow away from extinction. At N=KN^*=K, f(K)=r<0f'(K)=-r<0, so the carrying capacity is stable — perturbations decay back to KK.

A worked example

Take r=0.5 yr1r=0.5\ \text{yr}^{-1}, K=1000K=1000, and N0=10N_0=10. The doubling time during early (near-exponential) growth is t2=ln2/0.51.39t_2=\ln 2/0.5\approx 1.39 years. Growth is fastest when N=K/2=500N=K/2=500, at rate rK/4=0.51000/4=125rK/4=0.5\cdot 1000/4=125 individuals per year. Using the closed form at t=10t=10 years: the factor (KN0)/N0=(100010)/10=99(K-N_0)/N_0=(1000-10)/10=99, and ert=e50.006738e^{-rt}=e^{-5}\approx 0.006738, so N(10)=10001+990.006738=10001.667600.N(10)=\frac{1000}{1+99\cdot 0.006738}=\frac{1000}{1.667}\approx 600. The population has climbed from 10 to about 600 and is now just past its fastest-growth point.

In code

We solve the logistic ODE numerically and overlay the exact sigmoid to confirm they agree.

R

library(deSolve)

logistic <- function(t, N, p) list(prN(1N/pr * N * (1 - N / pK))
p <- list(r = 0.5, K = 1000)
times <- seq(0, 20, by = 0.1)
out <- ode(y = c(N = 10), times = times, func = logistic, parms = p)

# closed form
N0 <- 10
exact <- pK/(1+((pK / (1 + ((pK - N0) / N0) * exp(-p$r * times))
$max(abs(out[, "N"] - exact))   # ~1e-4: numerical and exact agree

Python

import numpy as np
from scipy.integrate import solve_ivp

r, K, N0 = 0.5, 1000.0, 10.0
f = lambda t, N: r * N * (1 - N / K)
t = np.linspace(0, 20, 201)
sol = solve_ivp(f, (0, 20), [N0], t_eval=t, rtol=1e-8)

exact = K / (1 + ((K - N0) / N0) * np.exp(-r * t))
print(np.max(np.abs(sol.y[0] - exact)))  # ~1e-6: they match
print(exact[t == 10.0])                  # ~600 at t = 10
4.199852662623016e-05
[599.85960181]

Julia

using DifferentialEquations

r, K, N0 = 0.5, 1000.0, 10.0
f(N, p, t) = r * N * (1 - N / K)
prob = ODEProblem(f, N0, (0.0, 20.0))
sol = solve(prob, Tsit5(); saveat = 0.1)

t = sol.t
exact = @. K / (1 + ((K - N0) / N0) * exp(-r * t))
maximum(abs.(sol.u .- exact))   # tiny: numerical solution matches the sigmoid

Why it matters

Exponential growth is the null model of population change and the engine of early epidemic spread, where case counts double every ln2/r\ln 2/r time units. The logistic adds the single most important biological correction — density dependence — which is exactly the mechanism that makes an epidemic’s susceptible pool deplete and turns unlimited growth into a saturating curve. Understanding these two models, their equilibria, and their stability is the foundation on which structured, discrete, and compartmental models are built.