# Planning a tracking plan

> How to decide what to track before you write any code, with worked examples for a SaaS signup flow and an ecommerce checkout.

Section: Best practices. Canonical page: https://mrkr.app/docs/best-practices/tracking-plan. Last updated: 2026-10-03.

Start from the question you want answered, not from the code you're about to ship. Work backwards from the question to the events that answer it.

## Start from the question

Before naming a single event, write down the decisions you're trying to inform: Are people finishing signup? Where do trial users stall? Which channel brings buyers, not just visitors? Each question implies a small number of events and, usually, one funnel. Events that don't trace back to a question are noise you'll never look at again, and they crowd out the ones you would have.

Pageviews and the built-in engagement events already answer a lot of this for free: which pages people land on, where they go next, how long they stay, and which links take them off-site. A tracking plan is really a short list of the handful of *product-specific* moments none of that can see: a plan chosen, a trial started, a report exported.

## Worked example: SaaS signup flow

| Question | Event | Notes |
| --- | --- | --- |
| Did they reach the pricing page? | pageview `/pricing` | Already tracked, no code needed |
| Did they start signing up? | `signup_started` | Fire on form focus or step 1 submit |
| Did they finish? | `signup_completed` | Star this as a conversion; it's the funnel's last step |
| Did they actually use the product? | `project_created` | The real activation moment, not just an account existing |

That's a 4-step funnel: pricing → signup started → signup completed → project created. Mark `signup_completed` as a conversion from the Events page so it's available everywhere a conversion rate is shown, not just inside this one funnel. See [funnels](https://mrkr.app/docs/analyze/funnels).

## Worked example: ecommerce checkout

| Question | Event | Notes |
| --- | --- | --- |
| Did they look at a product? | pageview `/products/:id` | Already tracked |
| Did they add to cart? | `added_to_cart` | Property: `product_id` or `category`, not both if you're near the 8-key budget |
| Did they start checkout? | `checkout_started` |  |
| Did they pay? | `mrkr.revenue(amount, { order_id })` | Ties directly into the revenue rollups and ARPV: see [reference/metrics](https://mrkr.app/docs/reference/metrics) |

## Don't track everything

> **Eight properties is a budget, not a suggestion:** Every event gets 8 property slots. Spend them on what changes a decision (plan, source, item category), not on what's merely available. A payload with 20 fields doesn't get you 20 dimensions; it gets you 8, chosen by sorting keys alphabetically and dropping the rest, which is rarely the 8 you meant.

Resist instrumenting things the tracker already covers (outbound links, file downloads) just because you can see the code. Hand-instrumenting a link that already emits `outbound` produces a near-duplicate event under a different name, not new information, and every "how many clicks" number you read afterwards is doubled: see the double-counting section of [accuracy](https://mrkr.app/docs/best-practices/accuracy). Start with the smallest plan that answers your actual questions, ship it, and add events when a real question comes up that the current ones can't answer.

> **Cost is not a reason to track less:** Custom events are free: only pageviews count toward your plan's quota. Keep a tracking plan small because a large one is unreadable and unmaintained, not because it costs money. See [what counts toward your quota](https://mrkr.app/docs/billing/what-counts-as-an-event).

For the mechanics of sending an event, see [custom events](https://mrkr.app/docs/tracking/custom-events).
