# Cohort Charts

> Retention and cohort visualization - triangle heatmaps, retention curves, layer-cake revenue charts, and survival views; cohort construction, the fixed-denominator rule, small-cohort suppression, immature-period marking, and reading the diagonal versus the row. Trigger on "cohort view", "retention chart", "churn curve", "heatmap", "layer cake", "NRR by cohort", "survival", "retention by month", "triangle chart".

- Skill: `lukehle/cohort-charts` (Agent Skill)
- Install (CLI): `npx skillmds@latest add lukehle/cohort-charts`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lukehle/cohort-charts/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: Lukehle (https://skillmd.com/u/lukehle)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/lukehle/cohort-charts

---


# Cohort charts

A cohort chart answers whether the business is getting better at keeping customers — which a single
blended retention number cannot, because blended retention mixes a good recent cohort with a bad old
one and reports the average.

---

## Construction rules — get these wrong and the chart lies

**Fixed denominator.** Measure each cohort against **its own starting population**, tracked forward.
Measuring against a moving denominator that includes new customers dilutes churn and makes retention
look better than it is. This is the most common way cohort retention gets overstated.

**One cohort assignment, forever.** A customer belongs to the cohort of their first period and never
moves. Reassigning on upgrade or reactivation destroys comparability.

**Logo and revenue are different charts.** Never mix them on one grid. Logo retention counts
customers; revenue retention counts dollars and can exceed 100% through expansion. Show both — the
divergence is the insight. High logo churn with low revenue churn means you are losing small
customers, which is a go-to-market signal rather than a product crisis.

**Define reactivation explicitly.** A customer who lapses and returns is either new or resumed, and
that is a decision you record, not one you leave implicit.

---

## The triangle heatmap

Rows are cohorts, columns are periods since acquisition. The characteristic staircase comes from
recent cohorts having fewer periods of history.

```
Cohort    n     M0    M1    M2    M3    M4    M5
2026-01  142   100%   88%   84%   81%   80%   79%
2026-02  156   100%   90%   86%   84%   83%
2026-03  201   100%   91%   88%   86%
2026-04  188   100%   89%   87%
2026-05  173   100%   92%
2026-06   94   100%
```

Non-negotiables:

- **Show `n`, the cohort size.** 120% retention on a 4-customer cohort is one upsell. Without `n` the
  reader cannot weight what they are seeing.
- **Suppress cells under 5 entities.** They are noise, and they can identify individual customers.
  Mark them as suppressed (`—` with a note), never leave them blank — blank reads as zero.
- **Do not truncate the immature tail.** Recent cohorts have fewer columns; that is honest. Dropping
  partial periods biases the curve upward, because the periods you drop are the ones with attrition
  still to come.
- **Mark partial periods** — a month-to-date column is not comparable to a complete one.
- **Sequential colour ramp**, not categorical, not diverging. Retention is ordered. Use diverging only
  when charting *change versus a target*, which has a real midpoint.
- Colour ramp needs enough lightness range to survive greyscale, and cells should carry their values
  as text anyway — the colour is the pattern, the number is the fact.

### Reading it

- **Along a row** — how one cohort decays over its life
- **Down a column** — whether newer cohorts retain better at the same age. **This is the improvement
  signal**, and it is the reason to build the chart
- **Along the diagonal** — everyone's experience in the same calendar month. A bad diagonal means
  something happened *then* — an outage, a price change, a billing failure — affecting all cohorts at
  once regardless of age

That diagonal read is the one most people miss, and it is often where the actionable finding is.

---

## Retention curves

The same data as lines: x is periods since acquisition, y is retention, one line per cohort.

Better than the heatmap for **trend across cohorts**; worse for spotting the calendar-month diagonal.
Build both when the question is "are we improving".

- Colour by cohort **recency** with a sequential ramp — older cohorts lighter, newer darker. A
  categorical palette here throws away the ordering the reader needs.
- Label lines directly at their right end rather than using a legend of twelve entries.
- Overlay a median or a target curve for reference.
- Curves flatten — that plateau is the durable base. Where it settles matters more than the initial
  drop.
- Do not smooth between periods. Monthly retention is monthly (`ui-antipatterns`).

---

## Layer cake

Stacked area of revenue by cohort over calendar time. Each band is a cohort; total height is total
revenue.

The single best chart for showing that **growth is compounding rather than churning through
customers**. Bands that persist and thicken mean expansion; bands that thin means the base is
leaking and new sales are refilling a bucket.

- Order bands oldest at the bottom, newest on top — the growth story reads upward.
- **Only the bottom band and the total are precisely comparable** (a stacked-area limitation); do not
  ask the reader to compare middle bands.
- Cap at ~12 cohorts before grouping older ones into a single base band.

---

## Cohort NRR

Net revenue retention for a cohort at a given age, charted as a line across cohorts.

- Plot at a **fixed age** (for example NRR at month 12) so cohorts are compared like for like. NRR at
  "latest available" compares a 3-month-old cohort with a 24-month-old one, which is meaningless.
- That constraint means the newest cohorts are absent from the chart. Say so rather than leaving a
  gap the reader interprets as a decline.
- Band the stage-appropriate benchmark, and label the stage (`chart-annotation`).

---

## Common failures

| Failure | Effect |
|---|---|
| Moving denominator | Retention overstated, sometimes dramatically |
| No cohort size shown | Small-cohort noise read as a trend |
| Immature periods dropped | Curve biased upward |
| Logo and revenue on one grid | Two different claims read as one |
| Categorical palette on an ordered dimension | Ordering discarded |
| Blank suppressed cells | Read as zero |
| Comparing NRR at different ages | Not a comparison at all |
| Too many cohorts | Unreadable; group older ones |

---

## Related skills

- `chart-selection` — when a cohort view is the right form
- `svg-charting` — building the grid and the ramp
- `design-tokens` — sequential ramp tokens
- `artifact-accessibility` — greyscale survival of the ramp, values in cells
- `chart-annotation` — stating the diagonal or column finding in the title

