ContentsAct II · MakeKnow if it worked
Move 33
Instrument before you launch
Adding the analytics afterwards does not cost you the experiment. It costs you the before, and the before is worth about half your users.
The feature is live and somebody asks whether it worked. You add the events that afternoon, wait two weeks, and come back with numbers.
The usual version of this chapter says the counterfactual is gone at that point, and that is too strong to print. You can still create a control group after launch by putting the feature behind a flag and turning it on for half your users. The comparison survives.
What does not survive is the before, and the price of losing it turns out to be measurable.
What retrofitting actually destroys
Two things, and one of them has a number attached.
Your history is not backfilled. Google’s documentation puts it in one sentence: “Modified and new events do not apply to historical data.” The events you define today start existing today. Whatever the world looked like last month is not recoverable, because nothing was writing it down.
And pre-period data is worth roughly half your sample. This is the part worth knowing. Microsoft published a technique called CUPED that uses data from before an experiment to reduce variance in the result. Their finding: “Three important recent experiments showed variance reductions of 45%, 52% and 49% with one week of experiment and one week of pre-experiment data.”
Roughly half the variance removed, by having measured the same users beforehand. In practical terms that is the same statistical power on half the users, or in half the time. So instrumenting late does not merely delay you. It roughly doubles the traffic or the duration you need to reach the same confidence, forever, on that metric.
That is the actual bill, and it is why this is a precondition rather than a task. As Kohavi, Tang and Xu put it: “Before you can run any experiments, you must have instrumentation in place to log what is happening to the users and the system.”
It drifts unless it is a rule
This is not a discipline problem you can solve by intending to do better. GitLab published their own audit of it, and the numbers are worth sitting with: they were shipping around 30 features per milestone, and analysis found “only 50% of our premium features are currently instrumented.”
A company that publishes its handbook, with an analytics team, found half its paid features had no measurement on them. Whatever your team’s number is, it is not better than that by accident.
The move
Write the events in the same pull request as the feature, and treat a feature with no events the way you would treat one with no tests.
BEFORE AFTER
PR #4412 "Add bulk edit" PR #4412 "Add bulk edit"
src/routes/admin.tsx src/routes/admin.tsx
src/lib/bulk.ts src/lib/bulk.ts
tests/bulk.test.ts tests/bulk.test.ts
analytics/events.ts <- same PR
ship. then, six weeks bulk_edit_opened
later, someone asks bulk_edit_submitted
bulk_edit_failed
add events. wait two
weeks. no baseline, and object_verb_pasttense, lower snake.
double the traffic needed one schema, one place, reviewed
for the same confidence like any other code
The naming matters more than it looks. Pick one convention, object_action in the past tense,
lower snake case, and hold it. Analytics event names are the one part of your codebase nobody
refactors, because renaming an event breaks every historical query that referenced it. You are
choosing these names once.
What it costs
Instrumentation is real work in every pull request, and it is the work people cut first when a sprint is tight. There is no version of this that is free. The honest framing is the same as move fifteen’s: it is a scope decision, so make it explicitly rather than by omission.
And the payoff is not uniform. CUPED’s own paper names its exception: “revenue-per-user, where CUPED reduced the variance by less than 5% due to the low correlation of revenue-per-user between the pre-experiment and the experiment periods.” Pre-period data helps most for metrics where a user’s past behaviour predicts their future behaviour, and barely at all for lumpy ones. Do not promise your team a halving on every metric.
Also, the data you do collect expires. Google’s retention for user-level data is 2 or 14 months, and for other event data up to 38 on the paid tier. A baseline you captured three years ago may not be there. Check your retention setting before you rely on history you assume exists.
Try this week
Open the last three features your team shipped and check whether each one emits a single event.
Most teams find one of the three does. That is the finding, and it is more persuasive to a sceptical lead than any argument about rigour, because it is about their own product.
Then take whatever you are building next and add one line to the pull request template:
Events emitted: …
Not a schema, not a taxonomy, not a project. One line that is empty until somebody fills it, in the same review where you would notice a missing test.