Why sinks hold high density

ecology tutorial
R
population ecology
conservation
habitat selection
Why a sink can hold more animals than the source that feeds it, worked in R, and why population density alone is a treacherous guide to habitat quality.
Author

Tidy Ecology

Published

2026-07-02

Modified

2026-10-07

Corrected 7 October 2026: the closing section said that animals filling the good habitat first keep the sink from ever getting crowded; it now says that the post’s own arithmetic already fills the source first and the sink still dwarfs it, and that how animals settle decides instead whether the sink fills before the source is full.

Setup: packages, colours and plot theme
knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE,
                      dev = "png", dpi = 120, fig.path = "figures/",
                      fig.width = 7, fig.height = 4.4)
library(ggplot2)
theme_te <- theme_minimal(base_size = 12) +
  theme(panel.background = element_rect(fill = "#f5f4ee", colour = NA),
        plot.background  = element_rect(fill = "#f5f4ee", colour = NA),
        panel.grid.minor = element_blank(),
        plot.title = element_text(face = "bold", size = 12))
theme_set(theme_te)
col_source <- "#3a6b52"; col_sink <- "#b5651d"; col_ref <- "#555555"

l1 <- 1.5; l2 <- 0.84; n1 <- 100
n2 <- n1 * (l1 - 1) / (1 - l2)
ratio <- n2 / n1

set.seed(408)
imm <- 40
habitat <- data.frame(lambda = seq(0.5, 1.5, length = 25))
habitat$density <- ifelse(habitat$lambda >= 1, 80 + rnorm(25, 0, 4),
                          pmin(imm/(1 - habitat$lambda), 400))
cor_dq <- cor(habitat$lambda, habitat$density)
dens_top <- habitat$lambda[order(-habitat$density)[1:3]]

The previous post ended on a warning: a habitat’s local growth rate tells you whether it can sustain itself, not how many animals it holds. This post makes that concrete with the result that most surprises people the first time they meet it. At equilibrium a sink can hold more individuals than the source that keeps it alive. The worst habitat on the landscape can be the most crowded.

The arithmetic of the paradox

A source at equilibrium is capped. It has a fixed number of breeding sites, and once they are full the extra production has nowhere to go but out, so the source sits at its own capacity and exports the rest. A sink has no such cap from below: it keeps accepting immigrants, and its population climbs until the annual shortfall between births and deaths, which grows with population size, finally balances the steady inflow. That balance point is the immigration divided by the per-capita shortfall.

l1 <- 1.5; l2 <- 0.84; n1 <- 100          # source growth rate, sink growth rate, source size
surplus <- n1 * (l1 - 1)                    # emigrants the source sends each year
n2 <- surplus / (1 - l2)                    # equilibrium sink size
c(source_size = n1, sink_size = n2, ratio = n2 / n1)
source_size   sink_size       ratio 
    100.000     312.500       3.125 

The source holds 100 breeding adults and exports 50 surplus animals a year. The sink, losing 16 per cent of its population to the shortfall each year, swells until that loss equals the inflow, which happens at 312.5, more than 3.1 times the source. Stand in each habitat and count: the sink looks like the stronghold and the source like the marginal patch. The count has it exactly backwards.

dp <- data.frame(habitat = c("source\n(grows locally)", "sink\n(shrinks locally)"),
                 N = c(n1, n2), kind = c("source", "sink"))
ggplot(dp, aes(habitat, N, fill = kind)) +
  geom_col(width = 0.6) +
  scale_fill_manual(values = c("source" = col_source, "sink" = col_sink), guide = "none") +
  labs(x = NULL, y = "Standing population", title = "The worst habitat holds the most animals")
Two bars: a short green source bar and a much taller ochre sink bar, with labels noting the source grows and the sink shrinks locally.
Figure 1: Standing population in the source and the sink. The sink (ochre, local growth rate below one) holds several times the source (green, local growth rate above one) that produces every surplus animal it receives.

Density is a trap for the manager

Now put the whole landscape together: many habitats of different quality, some sources, some sinks, all connected by movement. Plot the standing density in each against its local growth rate, the real measure of quality.

set.seed(408)
imm <- 40
habitat <- data.frame(lambda = seq(0.5, 1.5, length = 25))
habitat$density <- ifelse(habitat$lambda >= 1, 80 + rnorm(25, 0, 4),   # sources capped
                          pmin(imm/(1 - habitat$lambda), 400))          # sinks pile up near lambda = 1
c(correlation_density_quality = cor(habitat$lambda, habitat$density))
correlation_density_quality 
                 -0.2646964 

The correlation between density and quality is -0.26: if anything, slightly negative. The three most crowded habitats have local growth rates of 0.92, 0.96 and 0.88, every one of them a sink. A conservation plan that ranks habitats by how many animals they hold, a natural and common thing to do, will pour effort into the crowded sinks and neglect the sparse sources that are quietly producing the entire population (Van Horne’s warning, and the reason Pulliam 1988 The American Naturalist 132(5):652-661 mattered so much). Protect the sink and you protect a display; protect the source and you protect the supply.

habitat$kind <- ifelse(habitat$lambda >= 1, "source", "sink")
ggplot(habitat, aes(lambda, density, colour = kind)) +
  geom_vline(xintercept = 1, colour = col_ref, linetype = "dashed") +
  geom_point(size = 2.6) +
  scale_colour_manual(values = c("source" = col_source, "sink" = col_sink)) +
  labs(x = "Local growth rate (habitat quality)", y = "Standing density", colour = NULL,
       title = "Density does not measure quality")
Scatter of density against local growth rate; the highest densities occur at growth rates below one, and habitats above one are only moderately dense.
Figure 2: Standing density against local growth rate across a landscape of habitats. Density does not track quality: the densest habitats (ochre, sinks) grow less than one, while the true sources (green) can be sparse.

When the pattern appears, and when it does not

This upside-down world is not guaranteed: the sink’s equilibrium size is its inflow divided by its per-capita shortfall, so a small surplus or a sink that loses animals fast can leave it holding fewer animals than the source. Filling the good habitat first does not prevent it, though. The arithmetic above already works that way, with the source full and only its surplus spilling into the sink, and the sink still ends up dwarfing the source. How animals settle matters in another way: it decides whether the sink fills before the source is full. Animals that keep settling in the sink regardless, because they cannot tell it is poor, can crowd it even while good breeding sites stand empty. That is exactly the setting where a habitat can become a trap, luring settlers into a patch that quietly kills them, which is the next post. And because density has now failed twice as a guide to quality, the checking post turns to what you actually have to measure.

References

  • Pulliam HR 1988. The American Naturalist 132(5):652-661 (10.1086/284880).
  • Van Horne B 1983. The Journal of Wildlife Management 47(4):893-901 (10.2307/3808148).

Newsletter

Get updates by email

An occasional email when tutorials are added or substantially corrected. No spam; unsubscribe anytime.

By subscribing you agree to receive these emails and confirm your address once. See the privacy policy.