Product Analytics Event Taxonomy
Why Taxonomy Is the Real Product, Not the Analytics Tool
The most common reason a product analytics rollout fails isn't the choice between Mixpanel, Amplitude, or PostHog — it's an inconsistent event taxonomy that makes the data impossible to trust. If five different teams each instrument 'user signed up' as Signup Completed, signup_completed, sign_up_finished, and SignUp, no funnel or retention report built on top of that data can be trusted without manual reconciliation. Taxonomy design is a governance exercise that has to happen before instrumentation sprawls across a codebase, not after.
A Naming Convention That Scales
The most durable convention is Object + Action, in a single consistent case (snake_case is standard for most warehouses and analytics tools): signup_completed, checkout_started, invite_sent, feature_enabled. Avoid verb-first naming (completed_signup) since it breaks alphabetical grouping in event-pickers and makes related events (all signup_* events) harder to scan. Reserve past-tense verbs for things that happened (order_placed) and present-tense or noun-based names for state changes (subscription_active) — mixing tenses inconsistently across your taxonomy is a subtle but real source of confusion during analysis.
Event naming patterns
| Pattern | Example | When to Use |
|---|---|---|
| Object_Action (snake_case) | checkout_started | Default for almost all discrete user actions |
| Noun-only state event | subscription_active | Describing a state change rather than a discrete action |
| Namespaced by surface | mobile_app_push_opened | When the same logical action differs meaningfully by platform/surface |
| Avoid: free text labels | "User clicked the blue button on homepage" | Never — unqueryable, un-aggregatable, and breaks every dashboard |
Properties, Not Event Name Proliferation, Should Carry Variation
checkout_started_mobile, checkout_started_desktop, checkout_started_promo. This fragments every funnel and forces analysts to manually reconstruct 'all checkout starts' by unioning dozens of event names. Instead, use one checkout_started event with a platform and has_promo_code property — aggregation and segmentation become a property filter instead of a maintenance burden across your entire taxonomy.// A typed event contract, enforced at build time, prevents the
// typo/drift problem that breaks taxonomies at scale.
type CheckoutStartedEvent = {
name: 'checkout_started';
properties: {
cart_value: number;
currency: 'USD' | 'EUR' | 'GBP';
item_count: number;
platform: 'web' | 'ios' | 'android';
has_promo_code: boolean;
};
};
function track<E extends { name: string; properties: object }>(
event: E['name'],
properties: E['properties']
): void {
analytics.track(event, properties);
}
// Compile-time error if a property is missing, mistyped, or the
// event name doesn't match a registered contract.
track<CheckoutStartedEvent>('checkout_started', {
cart_value: 149.5,
currency: 'USD',
item_count: 2,
platform: 'web',
has_promo_code: false,
});Governing Who Can Add New Events
Without a review step, every new feature ships with its own ad hoc events named by whichever engineer happened to write that PR. A lightweight but effective governance pattern: maintain an event registry (a shared spreadsheet, a Lexicon/governance tool in your analytics platform, or a schema file checked into the repo) that any new event must be added to before shipping, reviewed by whoever owns analytics or data. This doesn't need to be heavyweight bureaucracy — even a PR template checklist item ("Does this add a new tracked event? Link the registry entry.") catches most drift before it compounds.
Design Properties Around Future Questions, Not Just Current Dashboards
Auditing an Existing Taxonomy
For teams inheriting an already-sprawling event taxonomy, start by pulling a full distinct list of event names and their fire counts over the last 90 days from your analytics platform or warehouse. Near-duplicate names, events with near-zero volume (likely dead code still firing), and events missing expected properties are the highest-value cleanup targets — consolidate or deprecate aggressively before adding any new governance process, since a clean baseline is what makes ongoing governance sustainable.
What's Next?
A clean taxonomy is the foundation that specific analyses — like tracking whether users actually adopt a new feature over time — depend on, and that's the next natural application of this groundwork.
I build these systems professionally.
Whether it's a RAG pipeline, analytics migration, or AI workflow — let's talk.