Product analytics
A metric is a claim about the world. Most disputed numbers are not wrong arithmetic — they are two
people using the same word for two different denominators, or a dashboard built on an event that
was never emitted on the path that matters.
When this fires
Someone is about to define, report or argue about a product number: activation, conversion,
retention, funnel drop-off, adoption of a feature. It also fires before instrumentation is added,
which is the cheapest moment to get it right. It does not fire when the metric definition is
already settled and the task is only to compute or chart it.
Four states, not one
Keep these apart in every sentence you write, because conflating them is how a metric that does not
exist ends up on a slide:
- Defined — written down with numerator, denominator, population, window.
- Instrumented — the emitting code exists on every path that should count.
- Collecting — events are arriving in the destination, from real traffic, since a known date.
- Reconciled — the number has been checked against an independent source and agrees.
Only the fourth is a number you may quote without a caveat.
Procedure
- Name the decision the metric serves. Who changes what behaviour at which threshold. If no
answer, say so — a metric nobody will act on is not worth the instrumentation cost, and saying
that is a legitimate result of this procedure.
- Write it as a rate with both halves visible. Numerator, denominator, the population each is
drawn from, and the time window. "Activation rate" is not a definition. "Accounts created in
week W that reached first successful import within 7 days / accounts created in week W" is.
- Fix the unit of aggregation — user, account, session, device, request — and use the same
unit on both halves. A per-session numerator over a per-user denominator is the most common
silent error in this whole area, and it never announces itself.
- Specify each event precisely: the name, the exact moment it fires, the properties carried,
and the near-miss cases it deliberately excludes (retries, server-side replays, internal or
test accounts, bot traffic). Write the exclusions down; they are the part that gets lost.
- Find the emitting code before believing the event exists. Search the repository for the
event name and read every call site. Check the paths nobody remembers: the mobile client, the
API-only path, the error branch, the redirect that returns early. Absent call site means the
metric is defined, not instrumented — report that, do not estimate around it.
- For a funnel, pin the entry cohort once and carry it through. Decide and record: must the
steps occur in order; what attribution window each step has; are users who enter twice counted
twice. A funnel whose steps each have their own population is four unrelated numbers in a row.
- Add a guardrail or counter-metric. Any metric that can be moved by degrading something else
— speed at the cost of errors, signups at the cost of retention — gets the opposing metric
defined alongside it, or it will be gamed by accident.
- State the trustworthy-from date. The first date the current definition and the current
instrumentation both held. Before that date the series is a different metric wearing the same
name; do not chart across the boundary without marking it.
- Reconcile against something independent before publishing: a database count, billing
records, a manual count for one day, the previous system. Report the gap as a number and its
likely cause. Agreement within a stated tolerance is the evidence; "looks about right" is not.
- Stop and ask before anything outward-facing. Adding tracking to production, changing the
semantics of an event other dashboards already use, publishing a dashboard others will act on,
or collecting a new property about people. Especially: never add personal data — email, name,
free-text input, precise location, anything identifying — to event properties on your own
judgement. Propose it, name the field, and wait.
Checklist
Failure handling
- Two sources disagree — do not average them and do not pick the friendlier one. Take one
narrow slice (one day, one account) and trace it through both until the divergence is a named
cause: a missing call site, a timezone, a deduplication rule, a filter on one dashboard.
- The event is not instrumented — the finding is "not measurable today", with the list of paths
that would need to emit. An estimate derived from a proxy is a proxy: label it as one, every
time it is quoted.
- The event fires more than once per real occurrence — say whether the metric counts events or
distinct units, and fix the definition rather than the data.
- Historical data does not go back far enough — report the window you actually have. Never
backfill by assumption and present the result as history.
- The definition already exists somewhere — use it, or change it deliberately and say so. A
second definition of an existing name is worse than a bad definition of a new one.
- Personal or sensitive data appears in event properties — stop, name the field and where it is
emitted, and raise it. Do not quietly keep querying it.
Evidence to report
The metric written out in full — numerator, denominator, population, window, unit. The file paths
and call sites where each event is emitted, and the paths found to be missing it. The exclusion
list. The trustworthy-from date. The reconciliation: both numbers, the gap, the explanation. And
the parts still unmeasurable, named as such rather than approximated into the table.
1---2name: product-analytics3description: Define a product metric so it means one thing — event, denominator, population, window — and check the instrumentation exists before anyone reports a number. Use when asked "how do we measure this", when a funnel or activation/retention/conversion metric is being defined, when two dashboards disagree, or before adding tracking to a feature. Not for choosing what to build (prioritization), not for designing an A/B test (experimentation), and not for general data analysis of a dataset that is already trusted.4---56# Product analytics78A metric is a claim about the world. Most disputed numbers are not wrong arithmetic — they are two9people using the same word for two different denominators, or a dashboard built on an event that10was never emitted on the path that matters.1112## When this fires1314Someone is about to define, report or argue about a product number: activation, conversion,15retention, funnel drop-off, adoption of a feature. It also fires *before* instrumentation is added,16which is the cheapest moment to get it right. It does not fire when the metric definition is17already settled and the task is only to compute or chart it.1819## Four states, not one2021Keep these apart in every sentence you write, because conflating them is how a metric that does not22exist ends up on a slide:2324- **Defined** — written down with numerator, denominator, population, window.25- **Instrumented** — the emitting code exists on every path that should count.26- **Collecting** — events are arriving in the destination, from real traffic, since a known date.27- **Reconciled** — the number has been checked against an independent source and agrees.2829Only the fourth is a number you may quote without a caveat.3031## Procedure32331. **Name the decision the metric serves.** Who changes what behaviour at which threshold. If no34 answer, say so — a metric nobody will act on is not worth the instrumentation cost, and saying35 that is a legitimate result of this procedure.362. **Write it as a rate with both halves visible.** Numerator, denominator, the population each is37 drawn from, and the time window. "Activation rate" is not a definition. "Accounts created in38 week W that reached first successful import within 7 days / accounts created in week W" is.393. **Fix the unit of aggregation** — user, account, session, device, request — and use the same40 unit on both halves. A per-session numerator over a per-user denominator is the most common41 silent error in this whole area, and it never announces itself.424. **Specify each event precisely**: the name, the exact moment it fires, the properties carried,43 and the near-miss cases it deliberately excludes (retries, server-side replays, internal or44 test accounts, bot traffic). Write the exclusions down; they are the part that gets lost.455. **Find the emitting code before believing the event exists.** Search the repository for the46 event name and read every call site. Check the paths nobody remembers: the mobile client, the47 API-only path, the error branch, the redirect that returns early. Absent call site means the48 metric is defined, not instrumented — report that, do not estimate around it.496. **For a funnel, pin the entry cohort once** and carry it through. Decide and record: must the50 steps occur in order; what attribution window each step has; are users who enter twice counted51 twice. A funnel whose steps each have their own population is four unrelated numbers in a row.527. **Add a guardrail or counter-metric.** Any metric that can be moved by degrading something else53 — speed at the cost of errors, signups at the cost of retention — gets the opposing metric54 defined alongside it, or it will be gamed by accident.558. **State the trustworthy-from date.** The first date the current definition and the current56 instrumentation both held. Before that date the series is a different metric wearing the same57 name; do not chart across the boundary without marking it.589. **Reconcile against something independent** before publishing: a database count, billing59 records, a manual count for one day, the previous system. Report the gap as a number and its60 likely cause. Agreement within a stated tolerance is the evidence; "looks about right" is not.6110. **Stop and ask before anything outward-facing.** Adding tracking to production, changing the62 semantics of an event other dashboards already use, publishing a dashboard others will act on,63 or collecting a new property about people. Especially: never add personal data — email, name,64 free-text input, precise location, anything identifying — to event properties on your own65 judgement. Propose it, name the field, and wait.6667## Checklist6869- [ ] The decision this metric informs is written down, or its absence is flagged70- [ ] Numerator, denominator, population and window are all stated71- [ ] Both halves use the same unit of aggregation72- [ ] Every event's firing moment, properties and exclusions are specified73- [ ] Each event was located in the emitting code, on every path that should count74- [ ] Funnel entry cohort, step ordering and attribution windows are fixed75- [ ] A guardrail metric exists for anything that can be gamed76- [ ] The trustworthy-from date is stated77- [ ] The number was reconciled against an independent source, with the gap quoted78- [ ] Any new tracking or new property was proposed, not added7980## Failure handling8182- **Two sources disagree** — do not average them and do not pick the friendlier one. Take one83 narrow slice (one day, one account) and trace it through both until the divergence is a named84 cause: a missing call site, a timezone, a deduplication rule, a filter on one dashboard.85- **The event is not instrumented** — the finding is "not measurable today", with the list of paths86 that would need to emit. An estimate derived from a proxy is a proxy: label it as one, every87 time it is quoted.88- **The event fires more than once per real occurrence** — say whether the metric counts events or89 distinct units, and fix the definition rather than the data.90- **Historical data does not go back far enough** — report the window you actually have. Never91 backfill by assumption and present the result as history.92- **The definition already exists somewhere** — use it, or change it deliberately and say so. A93 second definition of an existing name is worse than a bad definition of a new one.94- **Personal or sensitive data appears in event properties** — stop, name the field and where it is95 emitted, and raise it. Do not quietly keep querying it.9697## Evidence to report9899The metric written out in full — numerator, denominator, population, window, unit. The file paths100and call sites where each event is emitted, and the paths found to be missing it. The exclusion101list. The trustworthy-from date. The reconciliation: both numbers, the gap, the explanation. And102the parts still unmeasurable, named as such rather than approximated into the table.