How to Write a Product Analytics Tracking Plan (Before You Ship, Not After)
Two weeks after a feature launches, someone asks “how’s adoption looking?” and the answer is a shrug, because nobody instrumented the thing that would answer that question. This happens constantly, and it’s not an engineering failure — it’s a planning failure. A product analytics tracking plan is the document that prevents it: a list of exactly which events, properties, and user actions get logged, written and reviewed before a single line of tracking code ships, not reverse-engineered from a dashboard that already has gaps in it.
What Is a Product Analytics Tracking Plan, Exactly?
A tracking plan is a spec for data, the same way a PRD is a spec for behavior. It answers, for every meaningful user action: what event fires, what it’s named, what properties get attached to it (plan tier, account age, feature flag state, whatever matters for later segmentation), and who’s responsible for confirming it fires correctly once it ships. It is not the analytics tool itself — Amplitude or Mixpanel, PostHog, and Segment all consume a tracking plan, but the plan is tool-agnostic and should be written before you’ve even finalized which of them you’re using.
Teams commonly conflate “we have analytics” with “we have a tracking plan,” and those are different states entirely. Having Amplitude installed tells you nothing about whether the events firing into it are the ones that actually answer your product questions. It’s a familiar pattern: a fully wired analytics stack that still can’t answer “did users find the new filter feature,” because nobody had defined what “finding” the filter feature meant as an event before it shipped.
Why Tracking Plans Usually Get Written After They’re Needed, Not Before
The conventional pattern is depressingly consistent: a feature ships, a stakeholder asks for adoption numbers two weeks later, someone discovers the relevant click isn’t tracked, an engineer bolts on a tracking call in a follow-up PR, and the resulting data starts from whatever date that PR merged — with no baseline, no pre-launch comparison, and often inconsistent naming from whatever the engineer chose under time pressure. The team ends up analyzing three weeks of partial data and drawing conclusions from it anyway, because three weeks of bad data feels better than admitting there’s no data.
This happens because tracking plans get treated as a “nice to have” the same way tests sometimes do — valuable in theory, always the first thing cut when a sprint runs long. The fix isn’t more enthusiasm for analytics. It’s making the tracking plan a required section of the spec itself, reviewed at the same checkpoint as the rest of the requirements, not an afterthought owned by whoever remembers to ask for it.
How to Build a Product Analytics Tracking Plan Before You Ship
Start from the questions you’ll need to answer after launch, not from the events themselves. If the feature is a new filter tool, the real question is “do users who apply a filter convert to a saved search at a higher rate than users who don’t” — and that single question implies at least three events: filter applied, filter cleared, and saved search created, each with properties tying them back to the same session and user.
Tracking Plan Template: One Row Per Event
| Event Name | Trigger | Key Properties | Owner | Question It Answers |
|---|---|---|---|---|
| filter_applied | User applies any filter | filter_type, result_count, session_id | PM | Are users engaging with filtering at all? |
| filter_cleared | User removes an active filter | filter_type, time_since_applied | PM | Are filters confusing or unhelpful once applied? |
| saved_search_created | User saves a filtered view | source (from filter vs. manual), filter_count | PM + Eng | Does filtering drive the intended downstream behavior? |
| onboarding_step_completed | User completes a wizard step | step_number, step_name, time_on_step | Growth | Where does onboarding actually lose people? |
Work backward from each row’s “question it answers” column — if you can’t state the question, the event probably shouldn’t exist. This is also where scope discipline matters: a tracking plan with forty events nobody will ever query is worse than one with eight events tied directly to decisions the team will actually make. Every added event is a small ongoing maintenance cost, and padding a tracking plan to “be thorough” creates the same rot problem it’s meant to prevent.
Naming Events and Properties So They Don’t Rot in Six Months
Pick one naming convention — object_action (filter_applied) or action_object (applied_filter) — and never mix them within the same plan. This sounds trivial until you’ve tried to query six months of data across events named button_click, buttonClicked, and click_button, all logging the same user action because three different engineers wrote three different tracking calls without a shared reference doc.
A real constraint that changes how this gets used: at a small team, one person can hold the entire taxonomy in their head, and a lightweight shared doc is enough. Past roughly 15 engineers touching the codebase, that stops working, and you need an enforced schema — usually a lint check or a shared events library that fails a build if someone tries to fire an unregistered event name. Skipping that step because “we’re not that big yet” is exactly how the button_click/buttonClicked mess starts; by the time the team notices, there’s a year of inconsistently-named history to clean up.
When This Breaks: The Dashboard Nobody Trusts
Here’s the specific way this breaks, and it’s one of the more expensive slow failures in product work: events get added inconsistently over eighteen months, nobody owns the taxonomy, and eventually a stakeholder builds a dashboard that quietly double-counts a metric because two differently-named events were both, unknowingly, measuring the same action. Someone presents that number in a board meeting. It’s wrong. Nobody catches it for two quarters, because it looked directionally plausible and nobody had a reason to audit it.
What you see when it happens: growing quiet distrust of the analytics stack, more decisions getting made on gut feel because “the numbers don’t seem right anyway,” and eventually a full quarter spent on a taxonomy cleanup project that could have been avoided by enforcing a naming convention and event registry from the start. The recovery is real but slow: audit every event definition against actual firing behavior, merge duplicates, deprecate — don’t delete — anything with historical data attached, and put an owner on the taxonomy going forward so it doesn’t drift again.
QA-ing a Product Analytics Tracking Plan Before Launch
Before any feature ships, someone needs to actually trigger every event in the plan in a staging environment and confirm it fires with the right properties — not assume it works because the code review looked correct. At Callisto, a 30-person fintech SaaS startup around $2.5M ARR, the team shipped a new onboarding wizard under a one-sprint deadline forced by a board-meeting demo date, and engineering pushed back hard on spending half a day of that sprint on tracking QA when the deadline was already tight. Product held the line, partly because the board demo itself depended on being able to show activation numbers the following week.
The QA pass caught two events firing with a null user ID under a specific browser condition — a bug that would have made the entire onboarding funnel unmeasurable for whatever fraction of users hit that path, discovered nowhere except by manually clicking through the flow and checking the raw event stream before launch. Fixing it cost ninety minutes. Discovering it two weeks post-launch, after the board demo, would have cost the company its only clean read on whether the new wizard actually worked — a case where the ninety minutes clearly paid for itself many times over.
The habit worth keeping: a five-minute QA checklist run against every event in the plan, in staging, before every launch — not sampled, not “spot-checked,” every single one. It’s tedious. It’s also the only thing standing between shipping and shipping blind. This is the same discipline an A/B test depends on — a test built on an unverified tracking plan produces a confident, wrong answer instead of no answer at all, and the confident wrong answer is worse. Whichever product analytics tool your team lands on, the tracking plan is what determines whether the dashboard it eventually feeds is something people actually trust.
This week, pull up the last feature your team launched and check whether you can actually answer the one question that mattered about it, using real data. If you can’t, that’s not a data problem — it’s a planning problem, and the fix starts with the next spec you write.
References
Segment — event tracking plan documentation and taxonomy guidance — https://segment.com/docs
Amplitude — analytics implementation and taxonomy best practices — https://amplitude.com/docs
Mind the Product — practitioner writing on product analytics and instrumentation — https://mindtheproduct.com