2DProduct analyticsGuide 05

Cohort retention heatmaps for product analytics

Compare how signup cohorts retain week over week with a matrix that makes the data's ragged edge explicit.

Weekly signup retention

Example data
Jul 6Jul 13Jul 20Jul 27Aug 3Aug 10Aug 17Aug 24Aug 31
W0W1W2W3W4W5W6W7W8
9 signup cohortsHover or focus a cell for details
Rows
Signup cohort
Columns
Weeks since signup
Value
Percentage retained

The pattern

What the data tells you

Read across a row to follow a cohort. The stepped edge omits weeks that newer cohorts have not reached.

Put each signup cohort on a row and each age interval on a column. Hide future cells instead of filling them with zeros, so a newer cohort is not misread as a failed cohort.

Retention is a matrix before it is a line chart. The heatmap shows the diagonal of product history, exposes drop-off bands, and keeps newer cohorts visually honest because future observations do not exist yet.

Build it in React

From data to heatmap

TypeScript / React

Prepare your data

Percent retained by cohort and age interval, with cells beyond the cohort's current age omitted from the grid.

Make the component yours

Start with this example. Adjust the labels, colours, and tooltips to fit your product.

cohort-retention.tsx
import { Heatmap } from "@thilakbhat/heatmap-ui";
import "@thilakbhat/heatmap-ui/styles.css";

// One row per signup cohort; newer cohorts have fewer weeks so far.
const retention = [
  [100, 62, 48, 39, 31],
  [100, 67, 52, 41],
  [100, 59, 46],
];

export function RetentionMatrix() {
  return (
    <Heatmap
      rows={retention.length}
      columns={5}
      values={retention}
      scale="quantile"
      isSlotHidden={(row, column) => column >= retention[row].length}
      cellContent={(cell) => `${cell.value}%`}
      rowLabels={["Aug 4", "Aug 11", "Aug 18"]}
      ariaLabel="Weekly cohort retention"
    />
  );
}
Key props
HeatmapisSlotHiddencellContentscale="quantile"
API reference

A few more details

Common questions

Cohort retention heatmaps, explained.

What is a cohort retention heatmap?

A cohort retention heatmap puts each signup or start cohort on a row and each age interval on a column, revealing how retention changes over the life of the cohort.

Why should future retention cells be hidden instead of set to zero?

A newer cohort has not reached the later intervals yet. Hiding those future cells keeps unavailable observations separate from genuine churn and prevents the retention matrix from overstating failure.

What data structure does a retention heatmap need?

Use a jagged array or a matrix with an explicit hidden-cell rule: one row per cohort and one value per observed week, month, or product-age interval.

Can a React retention heatmap show percentages inside cells?

Yes. Pass percentage values to Heatmap and use cellContent to format each visible value as a percentage while the colour ramp shows the relative retention band.