River
Y CombinatorBacked by Y Combinator
FREE TEMPLATE

Metric Definitions Document Template

Four documents and five sheets that pin every metric to the seven fields a number needs, and record what your reports compute today.

Free download  ·  No account needed

Metric Register entry

[Metric name, in the words the business already uses]

StatusAgreed, Proposed, Contested, Undefined or Retired
OwnerA named person who confirmed it in writing
Also calledEvery other word people say for this in meetings

Seven fields decide the number. A sentence carries two of them.

1AggregationSum, count, count distinct, average, last value
2ExpressionThe column, named as it exists in the source
3Population filterWhich rows are in, stated positively
4Anchor timestampWhich of the record's dates sets its period
5GrainThe smallest period the metric is valid at
6Empty periodA period with no rows: zero, or absent
7Source of recordThe one object that governs, not the tool

Fields four and six are why the argument recurs

Two reports anchored on different dates agree on the year and never on the month, so anyone who checks the annual total concludes they match. Whether an empty period is a zero changes every average and no total.

Additive across time

A flow sums across months. A stock does not, and a chart tool will total the column anyway.

A metric definition is not a sentence. Two teams can implement the same agreed wording faithfully and still put different numbers on the same slide. The wording never said which of a record's several timestamps anchors it to a period, or whether a day with no orders is a zero or is absent. Those are not details. Each one changes the figure, and each one is missing from almost every definition ever written in prose.

So the register carries seven fields per metric rather than a description: the aggregation, the expression, the population filter, the timestamp that dates a row, the grain, what an empty period reads as, and the source of record. dbt's metric spec asks for each of them as a separate key, because a semantic layer cannot compute a number until all seven are decided. Google publishes what the aggregation field alone is worth: a plain sum over a joined order table returns 80.00 where the shipping collected was 30.00.

And the register is only half of it. What each report actually computes is read out of the report into its own sheet and never edited to match, so a metrics doc describing a world your reports do not implement becomes a list of rows instead. Send River whatever publishes a number and it names the one field a disagreement turns on. For a single pair that has to be settled before a meeting today, the report reconciliation does that instead, and the template library has the sheets blank.

Three reports, one metric, and the fields that make them disagree

What each report computes, the register that resolves it, and the log that explains next quarter's question.

Definition As Built

Illustrative rows for a fictional B2B software company, Halden Systems, 90 staff. Metric: New Bookings, September.

ReportAggPopulation filterAnchor timestampEmptyShows
Sales dashboardSumClosed WonClose dateAbsent1,284,000
Finance workbookSumClosed Won, less creditedInvoice dateAbsent1,102,000
Board deckUnknownUnknownUnknownUnknown1,284,000

Two fields differ, and they account for the gap exactly. The anchor timestamp moves 196,000 out of September (nine deals closed in September and invoiced in October) and 28,000 into it (closed in August, invoiced in September). The filter removes a 14,000 deal that was later credited. Signed and summed: minus 196,000, plus 28,000, minus 14,000 is minus 182,000, which is the whole gap.

The board deck row is the important one. The number came from a pasted figure, so nothing about its definition can be read out of it. It is recorded as unknown rather than assumed to match the dashboard it agrees with, because assuming is how a conflict becomes invisible.

One row per metric per report, read out of the report and never edited to match the register.

Metric Register

One row per metric. Seven fields, and a status that says how much of it is settled.

MetricStatusAggAnchorEmpty periodSums over timeOwner
New bookingsContestedSumundecidedAbsentYesD. Halloran
ARRAgreedLast valueMonth endCarry forwardNoD. Halloran
Average deal sizeAgreedAverageClose dateZeroYesP. Iyer
Active accountsContestedCount distinctMonthAbsentNonone
Sales efficiencyUndefinedunknownunknownunknownunknownnone
SessionsVendor definedCountEvent timeAbsentYesP. Iyer

Sales efficiency is the worst row here and it looks the healthiest. It appears in the board pack every quarter and no report computes it reproducibly, so there is nothing to check a number against. In a document that lists metrics and definitions, it is indistinguishable from a row every report honours.

ARR does not sum across time. It is a stock, so a yearly figure is the last month rather than twelve added together. The field exists because a chart tool will total the column without being asked.

Agreed needs all seven fields, a named owner who confirmed them, and one report whose as-built row matches.

Definition Change Log

Net revenue retention was 112 percent in Q1 and 104 percent in Q2. Somebody asks why.

ChangeTypeEffectRestatedIs it the business
Downgrades now in the baseRedefinitionminus 5 ptsNoNo
Acquired accounts entered the baseScope changeminus 2 ptsNoNo
ResidualBusinessminus 1 ptn/aYes

Seven of the eight points are definition and scope. Without the log, the 8 point drop reads as a retention problem and somebody spends a quarter fixing one. One point is the business, and that is the only part worth a conversation about performance.

Neither change is restated, and that is the correct call. Both old figures were right under the definitions in force when they were reported. A correction restates because the old numbers were wrong. A redefinition does not, and restating one erases a number that was accurate at the time.

Q1 and Q2 are not comparable across this boundary. The annual figures still are, which is the distinction a chart with no annotation hides.

What's in the pack

01

Report Inventory

One row per thing that publishes a number, recording where its definition actually lives: a versioned file, a chart's own query, or a spreadsheet formula. One layer down sits the CRM field dictionary.

02

Definition As Built

What each report computes today, read out of the report, one row per metric per report, and never edited to match the register. Where a number is computed off a raw event export rather than a report, the analytics export runbook settles whether that window was complete first.

03

Metric Register

One row per metric carrying all seven fields, the owner who confirmed them, the consumers who read it, and whether it sums across time. Deciding which of them belongs on a screen is a separate job, and writing the dashboard spec is where it gets done.

04

Definition Change Log

Every change with the field, the effect size, the direction and its type, because the type decides whether history gets restated.

05

Known Conflict Log

The pairs that will never agree, each with its expected variance and which report to quote for which question.

06

Definition Standard

The seven fields, why each one changes the number, and the two extra questions a join and a stock metric each force.

07

What Makes Two Numbers Differ

Eight mechanisms with the signature each leaves on a gap, ordered so you stop at the first match instead of listing causes.

08

Change Policy

The eight change types and what each obliges. A correction restates history; a redefinition must not, and does not mean the old figure was wrong.

09

Dispute Procedure

What to say in the room while two numbers are on screen, and what to do in the ten minutes after. Downstream, a dashboard description keeps the agreed wording next to the chart.

How to use it

  1. 1

    Open in River, or take it blank

    Open the pack in River and hand it the reports, or download the Word documents and CSV sheets and fill them in yourself.

  2. 2

    Send whatever publishes a number

    Dashboard screenshots, a report export, the query behind a view, a semantic layer file, the spreadsheet finance actually uses. Two reports that disagree are the best thing to send.

  3. 3

    Record what they compute

    Each report's metrics get read into Definition As Built field by field. Anything that cannot be established stays unset and names what would establish it.

  4. 4

    Decide one field at a time

    Conflicts cluster on a handful of fields, so one decision usually settles several reports. Each one gets logged with the number it moved and who has to be told.

Frequently asked questions

Is this template free?

Yes. The zip is Word documents and CSV sheets, with no account and no card. Edit with AI is the optional half: the agent reads your reports, records what each one computes, and names the field a disagreement turns on. The other packs sit in the template library.

What format are the downloaded files?

Word (.docx) for the four documents, CSV (.csv) for the five sheets, zipped together. Excel, Numbers and Google Sheets open the sheets straight off the download. Nothing to convert, no proprietary format anywhere in it, and the same is true of the SOP library pack.

We already have a metrics doc nobody trusts. Where does that fit?

As a record of intent, held against what the reports do rather than used to fill the register. That doc is almost certainly a list of sentences, and a sentence carries two of the seven fields, so it cannot pin a number. It goes in as the agreed column and the reports supply the rest.

Why keep two definitions per metric instead of one?

Because they are two different facts and the gap between them is the finding. What a report computes is evidence. What the company agreed is a decision. A metrics document that holds only the second describes a world that does not exist inside the reports, and it looks complete while it does it.

Two of our reports disagree today. Does this fix that?

It names the field, which is the part that takes the time. Each mechanism leaves a signature: a proportional gap at every grain is the population filter, agreeing annually but never monthly is the anchor timestamp, totals matching while averages do not is the empty period rule. For one pair before a meeting, use the report reconciliation.

Do we have to restate history every time a definition changes?

No, and doing so is a common and expensive mistake. A correction restates, because the old numbers were wrong. A redefinition does not: those figures were right under the definition in force, and rewriting them destroys the record of what was actually reported. The change type in the log decides it.

What does 'Edit with AI' actually do?

It signs you up, installs this pack as a private workspace of your own, and puts the agent in front of empty sheets. Then you send reports in whatever shape you have them: a screenshot of a tile, a pasted formula, a query, an export, a board deck with the number already in it.

Pin the definition, then the number holds

Take the Word documents and CSV sheets blank, or open this exact pack in River and let it read what your reports compute first.

Edit with AI