Event Tracking Plan and Governance
An event tracking plan is the reviewable contract between application code and the people who use telemetry. It explains what one row means, why the event exists, which fields are allowed, who owns changes, and how the event will be validated. Without that contract, a technically valid JSON payload can still produce misleading rates, broken funnels, privacy risk, or dashboards no one owns.
Use one row per event contract:
| Field | Example |
|---|---|
| Event name | checkout_completed |
| Grain | One logical checkout after all internal attempts |
| Decision | Identify checkout steps with elevated terminal failure |
| Owner | Payments engineering |
| Trigger | Success or terminal failure |
| Required fields | event_id, status, checkout_step, duration_ms, timestamp_utc |
| Optional fields | account_id, plan, release, error_type |
| Prohibited content | Payment details, email, request body, raw error message |
| Retention | Product-approved operational window |
| Schema version | 1 |
| Consumers | Checkout reliability dashboard and terminal-failure alert |
| Validation | Synthetic success, decline, timeout, retry, and duplicate fixtures |
Define meaning before fields
Start with the decision and grain. “Checkout event” is ambiguous. “One logical checkout after all internal attempts” tells a reviewer what COUNT(*) represents and whether retries should create extra rows.
Write the terminal outcomes and exclusions. If abandoned checkouts cannot be observed, state that limitation. If a success event is emitted before an asynchronous fulfillment step, do not label it checkout_completed.
Classify every field
For each field, document:
- type and unit
- required, optional, or conditionally required status
- allowed values or maximum length
- source of truth
- whether it is personal, pseudonymous, sensitive, or unrestricted
- purpose: filter, group, join, calculate, correlate, or debug
- behavior when the value is unavailable
Use controlled taxonomies for status, error_type, feature, and other group-by dimensions. Keep high-cardinality identifiers only when an approved investigation or join uses them. Prohibit arbitrary nested payloads and unbounded strings.
Record downstream dependencies
List saved queries, dashboards, alerts, exports, experiments, and reports that depend on the event. A field rename is not complete until those consumers are updated or deliberately versioned.
For each operational query, record its denominator, time zone, late-arrival policy, retry treatment, minimum volume, and expected fixture result. The plan should link to the query or the relevant SQL recipe, not restate an undocumented metric name.
Review changes as contract changes
Additive optional fields are usually safer than changing existing meaning. Use a new field or schema version when a type, unit, grain, or category meaning changes. During rollout:
- Update the tracking plan and obtain the required review.
- Add or update deterministic fixtures.
- Deploy producers with backward-compatible fields.
- Inspect schema and null rates.
- Update consumers.
- Remove compatibility logic only after the historical and deployment windows permit it.
Never make a newly introduced configuration value mandatory until every runtime is prepared and a fallback plan is documented.
Assign an operating cadence
Review critical plans on a schedule and after incidents. Look for unused fields, unowned dashboards, category explosion, rising null rates, unexpected schema versions, and identifiers that no longer have a justified purpose. Delete or shorten retention for data that no longer earns its cost and risk.
Start with the Event Tracking Plan Template, then use Designing an Event Schema, Canonical Wide Events, and Instrumentation Testing in CI to implement and enforce the contract.