Why this matters
Event properties turn raw clicks into decision-ready data. As a Product Analyst, you will:
- Define which attributes (properties) must be captured for critical events like Sign Up, Purchase, Search, and Feature Use.
- Ensure analysts can segment, join, and calculate metrics reliably across platforms (web, iOS, Android, backend).
- Prevent data debt by keeping properties consistent, typed, and privacy-safe.
Real tasks you will face
- Specify required vs optional properties for a new Checkout Completed event.
- Review a pull request that adds a property and check naming, data type, and allowed values.
- Version a property without breaking downstream dashboards.
- Audit high-cardinality properties that inflate storage costs.
Concept explained simply
Events describe that something happened. Properties describe the context of that thing. Good properties are stable, typed, and reusable. They make queries easy and insights trustworthy.
Mental model
Think of an event as a sentence.
- Subject (actor): user_id, account_id.
- Verb (event): Purchase Completed.
- Context (properties): price, currency, items_count, coupon_code, device, country.
Your job is to design the context so it is unambiguous, minimal, and useful over time.
Key principles and property types
- Clarity over cleverness: product_id, not id or pid.
- Stable meaning: once defined, do not change semantics; add new properties instead.
- Typed and constrained: choose boolean, integer, float, string, enum, array, object; define allowed values for enums.
- Cardinality aware: prefer low/medium-cardinality properties for segmentation; avoid free-text when possible.
- Join-friendly: include identity properties (user_id, account_id, session_id) where relevant.
- Privacy-first: no raw PII unless essential and approved; prefer user_id over email; mask, hash, or drop sensitive data.
- Versioning: event_version or property-level version suffix if meaning changes.
Common property groups
- Identity: user_id, account_id, session_id, device_id.
- Business: plan_type, items_count, total_value, currency.
- Experience: page, screen, feature_name, ui_variant.
- Technical: app_version, os, device_type, network_type.
- Attribution: referrer, utm_source, campaign_id.
- Experiment: experiment_name, variant.
Naming conventions and data types
- Names: lower_snake_case, nouns for properties (coupon_code), booleans prefixed with is_/has_ (is_trial, has_coupon).
- Numbers: use integer for counts (items_count), float/decimal for money (total_value), alongside currency (ISO 4217) to avoid mixing units.
- Enums: define allowed values (payment_method: card | paypal | bank_transfer | apple_pay | google_pay).
- Timestamps: ISO 8601 strings or standardized epoch_ms; avoid locale-specific formats.
When to use an array or object
- Array: multiple values of the same type (coupon_codes: ["WELCOME10", "SPRING"]).
- Object: structured details (shipping: {"method": "express", "cost": 6.99, "currency": "USD"}). Keep objects shallow and stable.
Event vs property scoping
- Make it an event if it changes product state or lifecycle (Subscription Upgraded).
- Make it a property if it describes the context of an event (plan_type at the time of upgrade).
- Make it a user/account attribute if it persists beyond a single event (billing_country).
Worked examples
Example 1: Sign Up Submitted (web)
event: sign_up_submitted
required_properties:
- user_id: string (temporary ID before verification)
- method: enum [email_password, google_oauth, apple_oauth]
- referrer: enum [direct, organic, paid, social, referral, unknown]
- page_path: string (low-card path, e.g., "/signup")
optional_properties:
- campaign_id: string
- experiment: object { name: string, variant: string }
- device_type: enum [desktop, tablet, mobile]
notes:
- No email captured here unless strictly needed; prefer hashing if required.
- Add event_version if form flow changes semantics.
Example 2: Video Played (mobile)
event: video_played
required_properties:
- user_id: string
- video_id: string
- position_seconds: integer (start position)
- playback_quality: enum [144p, 240p, 360p, 480p, 720p, 1080p]
optional_properties:
- is_autoplay: boolean
- connection_type: enum [wifi, cellular, offline]
- app_version: string
notes:
- Keep position as integer to simplify aggregations.
- Avoid storing full video title (high-cardinality); use video_id.
Example 3: Feature Toggle Clicked
event: feature_toggle_clicked
required_properties:
- user_id: string
- feature_name: enum [dark_mode, smart_suggestions, beta_flag_x]
- is_enabled: boolean (state after click)
optional_properties:
- ui_variant: enum [control, variant_a, variant_b]
- screen: string (limited set)
notes:
- feature_name should be a controlled list, not free text, to avoid inflated cardinality.
Design in 6 steps
- Define the decision: what question will this event answer? (e.g., What is the conversion rate by payment_method?)
- List essential properties only: identity, business, context, experiment, technical.
- Choose data types and allowed values: prefer enums; avoid free text.
- Set constraints: required/optional, default values, cardinality expectations, null handling.
- Plan governance: owner, event_version, deprecation path, testing rules.
- Document a one-paragraph definition per property: how to populate, examples, anti-examples.
Deprecation pattern
When meaning changes, add a new property (payment_method_v2) or increment event_version. Keep old properties until downstream consumers migrate.
Quick checklist
- Does each property have a clear definition and data type?
- Are enums documented with allowed values?
- Are identity properties present to enable joins?
- Is PII excluded or minimized with safeguards?
- Are high-cardinality properties avoided or justified?
- Is there a versioning strategy?
- Will this design work across platforms?
Exercises
These mirror the exercises list below. You can complete them for free; saved progress is available to logged-in users.
Exercise 1: Design properties for Checkout Completed
Scenario: An e-commerce app wants a robust Checkout Completed event that supports revenue reporting, refund reconciliation, and A/B test analysis.
- Propose properties grouped as identity, business, context, experiment, and technical.
- Specify data types and allowed values where applicable.
- Mark required vs optional; add constraints and notes (e.g., cardinality, privacy).
- Provide a sample payload.
Hints
- Always include user_id or account_id, plus order_id for joins.
- Pair numeric monetary values with currency.
- Consider experiment data and coupon usage.
Show solution
event: checkout_completed
identity (required):
- user_id: string
- order_id: string
- session_id: string (if available)
business (required):
- items_count: integer
- total_value: float (order total after discounts, before tax if that is your standard)
- currency: enum [ISO 4217]
- payment_method: enum [card, paypal, bank_transfer, apple_pay, google_pay]
- shipping_tier: enum [standard, express, pickup]
- coupon_applied: boolean
- discount_value: float (0 if none)
context (optional):
- country: enum [ISO 3166-1 alpha-2]
- referrer: enum [direct, organic, paid, social, referral, unknown]
- device_type: enum [desktop, tablet, mobile]
- app_version: string
experiment (optional):
- experiment: object { name: string, variant: string }
technical (recommended):
- event_version: integer (e.g., 2)
constraints:
- total_value >= 0; discount_value >= 0
- coupon_applied == true implies discount_value > 0
privacy:
- Do not capture full card PAN or email. Use user_id and payment_method only.
sample payload:
{
"event": "checkout_completed",
"user_id": "u_123",
"order_id": "o_987",
"session_id": "s_abc",
"items_count": 3,
"total_value": 59.97,
"currency": "USD",
"payment_method": "card",
"shipping_tier": "express",
"coupon_applied": true,
"discount_value": 10.00,
"country": "US",
"referrer": "paid",
"device_type": "mobile",
"app_version": "3.2.1",
"experiment": {"name": "checkout_ui_v2", "variant": "variant_a"},
"event_version": 2
}
notes:
- Revenue calculations require consistent total_value semantics; document whether taxes are included.
Common mistakes and self-check
- Free-text where enum fits better: Replace payment_method="visa" with payment_method="card" and capture brand separately if needed.
- Mixing units: Never send total_value without currency.
- Changing meaning silently: If discount_value changes from absolute to pre-tax, increment event_version.
- PII leakage: Avoid email, full names, phone numbers; use stable IDs.
- Missing join keys: Always include user_id/order_id for transactional events.
- Duplicated properties across events with different semantics: Keep definitions universal or rename to avoid confusion.
Self-check mini audit
- Pick one event and verify each property has a clear, single meaning.
- Run through the checklist and mark gaps.
- Propose one improvement that reduces cardinality or increases clarity.
Practical projects
- Create a tracking plan for Search Performed, Add to Cart, and Purchase, including property definitions, enums, and sample payloads.
- Refactor a high-cardinality property (e.g., page_url) into lower-card alternatives (page_path, page_category).
- Propose a versioning strategy for a breaking change to an event payload, including migration notes.
Who this is for
- Product Analysts who define tracking specs for cross-platform products.
- Developers and data engineers collaborating on instrumentation.
- PMs seeking reliable self-serve analytics.
Prerequisites
- Basic SQL and event analytics concepts.
- Understanding of core metrics: conversion, retention, revenue.
- Familiarity with privacy basics (PII, hashing, minimization).
Learning path
- Review key principles and worked examples above.
- Complete Exercise 1 and validate with the checklist.
- Run the Quick Test to check understanding.
- Apply to a small real product area (e.g., onboarding) and iterate with stakeholders.
Next steps
- Document one production-ready event with properties, enums, and sample payload.
- Set up a lightweight review ritual for any new property (definition, type, justification).
- Track adoption and data quality weekly for your critical events.
Mini challenge
Pick an existing event with messy properties. Re-design them to reduce cardinality, add missing identity keys, and clarify money fields. Draft a migration note that includes event_version and deprecation steps.
Event Properties Design — Quick Test
Available to everyone for free. Progress is saved for logged-in users.