Skip to content
SlashClone

Retention cohorts

@usagemetrics/retention-cohorts

Build weekly or monthly retention cohorts for users or accounts from an events CSV. Writes the cohort table, a size-weighted average curve, where the curve flattens, and the best and worst cohorts, as markdown, CSV, and JSON.

SkillDatav1.0.0 (latest)Tested
Activity
New: be the first to try it
  1. 1---
  2. 2name: retention-cohorts
  3. 3description: Build retention cohort tables (weekly or monthly, by user or by account) from a product events export, with a size-weighted average retention curve, where it flattens, and the best and worst cohorts. Use when the user asks about retention, cohort analysis, "do users come back", "is retention getting better", logo retention by signup month, or wants a cohort triangle or heatmap for a board deck or product review.
  4. 4license: MIT
  5. 5---
  6. 6
  7. 7# Retention cohorts
  8. 8
  9. 9The classic retention triangle, done right: cohorts by first activity, incomplete periods left blank instead of shown as drops, and an average curve weighted by cohort size so one tiny cohort cannot swing it.
  10. 11## Inputs
  11. 13An events CSV in `data/` with `timestamp`, `account_id`, `user_id`, `event` (the same file the `saas-usage-dashboard` kit uses). Decide with the user:
  12. 151. **Period:** `month` for B2B tools used a few times a month; `week` for products used weekly or more. Default month.
  13. 162. **Entity:** `user` (do people come back?) or `account` (do customers keep using it?). Account retention is usually what leadership means by "logo retention" in usage terms.
  14. 173. **What counts as active:** by default any event. Logins and page views flatter retention, so suggest a list of meaningful events, for example `--active-events ran_query,created_report`. The cohort is still the first period with any event.
  15. 19## Steps
  16. 211. Check the date range. You need at least 4 complete periods; 12 is better.
  17. 222. Run:
  18. 24 ```bash
  19. 25 node scripts/cohorts.mjs data/events.csv --period month --entity user --active-events ran_query,created_report --out out/retention
  20. 26 ```
  21. 28 Other options: `--periods 12` (how many cohorts and columns), `--as-of 2026-10-31`, and `--include-current` to show the partial current period (off by default, since it always looks like a drop).
  22. 293. Read `out/retention.md` and report:
  23. 30 - Period 1 retention on average (M1 or W1) and the trend across recent cohorts.
  24. 31 - Where the curve flattens, if it does. A curve that flattens is the sign of product-market fit for that segment; one that keeps sliding is not.
  25. 32 - Best and worst cohorts, and a question about what was different then (launch, pricing change, a big customer onboarding, a holiday).
  26. 334. If the user wants a chart, `out/retention.csv` drops straight into a spreadsheet heatmap, or run `saas-usage-dashboard` for the weekly heatmap in HTML.
  27. 345. Offer a split: rerun on a filtered file (for example one plan or one acquisition channel) saved as `data/events-<segment>.csv`, and compare M1 and M3 side by side.
  28. 36## Reading the numbers
  29. 38- Cohorts under 10 entities are noisy. Say so instead of drawing conclusions from them.
  30. 39- Users can come back after a gap, so a later period can be higher than an earlier one. That is real, not a bug.
  31. 40- Retention by events is usage retention, not revenue retention. For revenue, use `arr-waterfall` from the Ledgerly account.
  32. 42## Output template
  33. 44```markdown
  34. 45**Monthly user retention (active = ran_query or created_report)**
  35. 46M1 58% on average, M3 45%, still sliding about 5 points a month after M3.
  36. 47Best recent cohort: 2026-06 (78% M1). Worst: 2025-11 (27% M1). What changed in June?
  37. 48| Cohort | Size | M0 | M1 | M2 | M3 | ...
  38. 49```
  39. 51## Guardrails
  40. 53- Never fill blank cells with zeros or estimates. Blank means "not observable yet".
  41. 54- Exclude internal and test users before running; ask how to recognize them (email domain, a test account ID).
  42. 55- Do not paste user IDs into chat.