For the complete documentation index, see llms.txt. This page is also available as Markdown.

Event & property naming

A short, opinionated style guide for event and property names.

There's no schema enforcement on event or property names — Millimetric will store whatever you send. But analytics taxonomies rot fast unless you have a convention. Here's ours.

Event names

snake_case, past tense, scoped to the actor.

✅  signup
✅  trial_started
✅  checkout_completed
✅  invite_sent
✅  agent_task_completed

❌  Sign Up
❌  signing-up
❌  signupCompleted
❌  Signup Successful

$-prefix is reserved

System events emitted by the SDK or the server start with $. Don't define your own $-events; they're indistinguishable from system ones in the dashboard.

| $pageview | Browser SDK on load and SPA navigation. | | $identify | Server, on POST /v1/identify. |

Verb in the past tense

signup is fine, but signed_up is better. Past tense reads naturally in funnel queries: "users who signed_up then subscribed".

That said, the existing convention in this codebase uses bare nouns/short verbs (signup, purchase, clicked_pricing) — both work. Pick one and stick to it.

Don't pack multiple events into a name

Property cardinality is cheap. Event-name cardinality is what kills your dashboards.

Roughly 30–50 events is plenty

If you have 200 distinct event names, you almost certainly should have fewer events with more properties.

Property names

snake_case. Type the value. Include units where ambiguous.

Booleans named as questions

is_paid, has_premium, was_invited, did_complete_onboarding. Reads nicely in WHERE clauses.

Units on numbers, always

duration_ms, amount_cents, latency_ms, size_bytes, weight_kg. Pick a unit per metric and never mix.

Money in cents

Or any fixed-precision integer. Never floats for revenue. amount_cents: 4900, plus currency: "usd". Always together.

$-prefix on properties means "ambient context"

The browser SDK adds $viewport_w, $viewport_h, $language, $timezone. Following that convention for your own ambient context ($session_user_role, $build_version) keeps event-specific properties visually distinct from cross-cutting ones.

Conventions tools rely on

If you set these with the listed names, dashboards and MCP tools will Just Work.

Property
Used for

utm_source, utm_medium, utm_campaign, utm_content, utm_term

Classifier (also reads them off url)

fbclid, gclid, ttclid, msclkid, li_fat_id

Classifier

amount_cents + currency

Revenue dashboards (roadmap)

experiment_id + variant

A/B test analysis (roadmap)

plan (string)

Cohort filtering on user-tier

path (on the event itself, not in properties)

Top-paths breakdown

A small starter taxonomy

Steal this for a SaaS product:

Event
When
Key properties

$pageview

every navigation

path, url, referrer (auto-captured)

signup

account created

plan, referral_code, invited

trial_started

trial begins

plan, trial_days

subscription_started

first paid charge

plan, amount_cents, currency, billing_period

subscription_changed

upgrade/downgrade

from_plan, to_plan, amount_cents, currency

feature_used

a notable in-app action

feature, result

invite_sent

user invites a teammate

count

support_ticket_opened

help requested

category, priority

error_shown

user-facing error

error_code, http_status

account_deleted

farewell

reason

For e-commerce, swap signup/trial_*/subscription_* for viewed_product, added_to_cart, removed_from_cart, started_checkout, completed_checkout, refunded. See the E-commerce recipe.

Renaming is a chore — pick now

There's no rename API. Renames happen by:

  1. Start emitting the new name.

  2. Wait for the retention window to pass (default 90 days).

  3. Old events expire, new events have the new name.

Or query both names with a CASE WHEN until the old one rolls off. Easiest by far is to pick a convention before you start and write it down somewhere your team will read it.

Last updated

Was this helpful?