Event Tracking Design
The schema that decides whether your analytics are trustworthy
Event tracking is a data contract: consistent names, typed properties and a shared dictionary. Done well it makes every metric trustworthy; done badly it silently corrupts analysis.
What you will learn
- Design an event with a name, properties and a trigger condition
- Apply a naming convention that stays stable under change
- Version and retire events without breaking dashboards
An event is a verb_noun action annotated with properties. The rule: capture the same user action with exactly the same event name and property shape everywhere, forever — then every metric built on it stays comparable.
What is this?
Event tracking design is the discipline of defining, naming and versioning the events your product emits. Each event is a contract: a stable name (for example product_purchased), a set of properties (amount, currency, payment_method, plan), and an explicit trigger condition. When the contract is respected everywhere — web, mobile, backend — analytics are comparable; when it isn't, the same metric means different things in different reports.
Why do you need it?
- Renamed events or reshaped properties break every dashboard, cohort and experiment that used them.
- A stable taxonomy lets new analysts read the data without tribal knowledge.
- Consistent identity (user_id, anonymous_id, device_id) is the precondition for cohort and LTV analysis.
- Well-specified triggers prevent double counting (SDK + server both logging the same purchase).
Mental model
A city's street naming rules
An event taxonomy
Every street has one unique name across the whole city; addresses work because the contract is universal. Randomly renaming streets would break mail, maps and emergency services — same for metrics.
How it works
- Choose a naming scheme such as {object}_{action} — signup_completed, plan_upgraded, report_created — and forbid synonyms (no sign_up_ok).
- Define every property's type, allowed values and meaning in the event dictionary.
- Capture identity at event time: user_id plus anonymous_id before login, resolved consistently.
- Emit events from one canonical layer (SDK or server) to keep a single source of truth.
- Version breaking changes — property rename = new event (signup_completed_v2) with a migration window; never mutate history.
Anatomy of one well-designed event.
Examples
A canonical event contract
// event: checkout_completed// trigger: ONE purchase id captured successfully server-side{ "event": "checkout_completed", "user_id": "u_8f21", "anonymous_id": "anon_7a3c", "properties": { "order_id": "o_9912", // string, unique "amount_usd": 49.00, // number, cents-free canonical "currency": "USD", // ISO 4217 "payment_method": "card", // enum: card | wallet | invoice "is_recurring": true // boolean }, "timestamp": "2026-09-22T14:03:11Z" // event time, UTC ISO 8601}The name is unique and stable, every property has one clear meaning, identity and event time are explicit, and the trigger ('purchase captured server-side') rules out double counting.
In production
- A fintech treats transaction events as authoritative server-side logs only — client SDKs can't emit them — eliminating duplicates from retries.
- A B2B SaaS versioned 'invite_sent' to 'invite_sent_v2' when the recipient field changed type, running both for a quarter before sunsetting v1.
- An event dictionary is checked into the repo and reviewed like code, so feature PRs must update the dictionary before merging.
Best practices
- Use a stable verb_noun convention in present-past tense consistently and document the rule.
- Record event time (client clock) and processed time (server clock) separately for latency analysis.
- Keep property sets small and typed; enums beat free text for analysis.
- Review tracking in code review and interrogate new events before approving.
Common mistakes
- Same logical action under multiple names (signup, registered, user_created) that later can't be aggregated.
- Mutating an existing event's properties and breaking the quarter-over-quarter comparison.
- Counting the same action twice because both the SDK and the backend emit it.
- Timestamping in the client's local timezone without a timezone marker.
Debugging tips
- Grep your analytics plan/spec for event name collisions before it reaches the data.
- Query the events table for a test user and verify payload shape after each deploy.
- When a funnel suddenly inflates, check for a second tracker emitting the same event.
- Use a diff of event schemas across environments to catch drift between staging and prod trackers.
Interview checkpoint
Hands-on lab
- Inspect a raw, messy events feed as a product team receives it
- Classify event naming and identity problems
- Build a canonical parsing layer with pandas that normalizes names, identity and timestamps
Audit an Event Feed and Rebuild a Canonical Taxonomy
30 min · intermediate
Quick quiz
Which event name best follows a stable taxonomy?
Historically logged events should be rewritten when a property name changes.