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.
- Activity
- New: be the first to try it
- Installs
- 0 installs
- Likes
- 0 likes
- Clones
- 0 clones
What it makes
Real output from this kit
- Sample file565 bytes, download to openRetentionFrom the kit's tests
- Sample file4 KB, download to openRetentionFrom the kit's tests
- Sample file1 KB, download to openRetentionFrom the kit's tests
How this works
- It is a skill: written instructions Claude reads when your request matches what the skill is for. You do not call it by name; just ask for the task.
- While it works, it reads and changes files in the places it lists, nowhere else.
- It runs these commands on your computer: node scripts/cohorts.mjs.
- Nothing runs until you choose to use it, and you can remove it any time.
SKILL.md
Retention cohorts
The 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.
Inputs
An events CSV in data/ with timestamp, account_id, user_id, event (the same file the saas-usage-dashboard kit uses). Decide with the user:
- Period:
monthfor B2B tools used a few times a month;weekfor products used weekly or more. Default month. - Entity:
user(do people come back?) oraccount(do customers keep using it?). Account retention is usually what leadership means by "logo retention" in usage terms. - 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.
Steps
- Check the date range. You need at least 4 complete periods; 12 is better.
Run:
node scripts/cohorts.mjs data/events.csv --period month --entity user --active-events ran_query,created_report --out out/retentionOther options:
--periods 12(how many cohorts and columns),--as-of 2026-10-31, and--include-currentto show the partial current period (off by default, since it always looks like a drop).Read
out/retention.mdand report:- Period 1 retention on average (M1 or W1) and the trend across recent cohorts.
- 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.
- Best and worst cohorts, and a question about what was different then (launch, pricing change, a big customer onboarding, a holiday).
- If the user wants a chart,
out/retention.csvdrops straight into a spreadsheet heatmap, or runsaas-usage-dashboardfor the weekly heatmap in HTML. - 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.
Reading the numbers
- Cohorts under 10 entities are noisy. Say so instead of drawing conclusions from them.
- Users can come back after a gap, so a later period can be higher than an earlier one. That is real, not a bug.
- Retention by events is usage retention, not revenue retention. For revenue, use
arr-waterfallfrom the Ledgerly account.
Output template
**Monthly user retention (active = ran_query or created_report)**
M1 58% on average, M3 45%, still sliding about 5 points a month after M3.
Best recent cohort: 2026-06 (78% M1). Worst: 2025-11 (27% M1). What changed in June?
| Cohort | Size | M0 | M1 | M2 | M3 | ...Guardrails
- Never fill blank cells with zeros or estimates. Blank means "not observable yet".
- Exclude internal and test users before running; ask how to recognize them (email domain, a test account ID).
- Do not paste user IDs into chat.
README.md
Retention cohorts
Builds the retention triangle from a product events export: weekly or monthly cohorts, by user or by account, with a size-weighted average curve and a note on where it flattens. Partial periods stay blank instead of showing up as fake drops.
Who it is for: product managers, founders, and growth folks who need to answer "is retention getting better?" for a product review or board deck.
Example
Input: examples/events.csv (about 1,250 events from about 130 users over 12 months).
Output (out/retention.md):
| Cohort | Size | M0 | M1 | M2 | M3 |
|---|---|---|---|---|---|
| 2025-11 | 11 | 100% | 27% | 27% | 27% |
| 2026-06 | 9 | 100% | 78% | 56% | 56% |
Average curve: M1 58%, M2 48%, M3 45%, M4 40%.
Best M1: 2026-06 (78%). Worst M1: 2025-11 (27%).Plus out/retention.csv for a spreadsheet heatmap and out/retention.json.
What it can access
- Runs
node scripts/cohorts.mjs(Node built-ins only). - Reads
data/. Writesout/retention*. - No network.
Setup
None. Export events (timestamp, account_id, user_id, event) to data/events.csv and ask Claude for retention cohorts.
Files
- README.md
- SKILL.md
- examples/events.csv
- kit.json
- scripts/cohorts.mjs
- scripts/lib.mjs
Did it work?
0worked for them0did not work
Sign in to say whether it worked for you.
Nobody has said yet. Tried it? Tell the next person.
