Client at $100K MRR bleeds 8% monthly churn. They want cohort retention tied to the ledger. Anyone modeling signup cohorts in Beancount?
cohort retention tied to the ledger
These live in different systems. Use each for its job. Beancount records money that moved; cohort retention is analytics about behavior over time. Retention math needs compounding monthly rates, logo versus revenue churn, and expansion offsetting contraction. That belongs in a script, not postings. If you must connect them, tag or note the signup month on income postings, export, then compute curves in Python. Per-cohort subaccounts look tidy for a month, then rot the moment plans change or customers upgrade. And at 8% monthly churn, roughly triple the sub-3.5% ChartMogul benchmark for small SaaS, the problem is onboarding, not ledger structure. Fix the first 30 days.
We tag every income posting with signup month for my SaaS client. Each month I run one BQL query per cohort age and the retention curve falls out. No sidecar to maintain, and tags don’t rot like subaccounts. James, what does your script catch that the query misses?
A balance query shows money present but misses what each customer did inside the cohort. Expansion at one account masks contraction at another, a reactivation reads as retained instead of won-back, and plan-change repricing moves MRR with no churn event. Your signup-month tags are the right input — my script reads those tags. We just differ on where the math lives. Happy to compare outputs.
Verdict: keep Bob’s signup-month tags in the ledger, run James’s script on top reading those tags.