In Mixpanel, how do event properties, profile properties, and super properties differ?
answer
- three places a value can live
- one is frozen, one is overwritten
- profile values are read as of now
- register stamps every later event
- segment history means put it on the event
basics
~20 sEvent properties are frozen onto one event when it fires. Profile properties live on the user and get overwritten, so reports read their current value. Super properties are stored in the client and auto-attached to every later event.
solid answer
~50 sMixpanel stores three different kinds of value. An **event property** is passed into the `track` call — `mixpanel.track('Song Played', { genre: 'jazz' })` — and is immutable, a permanent fact about that one event. A **profile property**, set with `mixpanel.people.set({ plan: 'pro' })`, hangs off the user identified by `distinct_id`; it is mutable, so when the plan changes the old value is gone and every report segmented on it reads today's value, even for events from a year ago. A **super property**, registered with `mixpanel.register({ plan: 'pro' })`, is persisted in the browser and merged automatically into every subsequent event from that device — that is how you stamp mutable state onto events so historical breakdowns stay correct. Properties beginning with `$`, such as `$email`, are Mixpanel's reserved namespace. Rule of thumb: if you will ever segment history by it, it belongs on the event.
code
javascript · 11 lines// Point-in-time: stamped on every later event from this browser
mixpanel.register({ plan: 'pro', locale: 'en-GB' });
// Immutable fact about one event
mixpanel.track('Checkout Completed', {
cart_value: 84.5,
payment_method: 'card'
});
// Current-state description of the user, overwritten on change
mixpanel.people.set({ plan: 'pro', $email: '[email protected]' });go deeper
Be able to name the three calls — track with properties, people.set, register — and say in one sentence what each one attaches a value to.
Explain why a profile property makes a historical breakdown non-reproducible, and show how registering a super property fixes it without editing every track call site.
Show judgment about which attributes are duplicated onto both the event and the profile, and how server-side tracking loses super properties so context must be attached explicitly in a shared wrapper.
Own the instrumentation standard: which attributes are point-in-time versus current-state, who approves new property names, and how you avoid a property sprawl nobody can interpret two years later.
## Why this distinction exists Mixpanel is an event store first and a user store second. Almost every report it draws — funnels, retention, flows, segmentation — is computed over a stream of timestamped events belonging to a `distinct_id`. Around that stream sit user profiles, which are a small key/value document per user. The three property namespaces exist because those two stores have completely different mutability rules, and confusing them is the single most common instrumentation mistake on the platform. ## Event properties An event property is supplied at the moment the event is recorded: ```javascript mixpanel.track('Checkout Completed', { plan: 'pro', cart_value: 84.5, payment_method: 'card' }); ``` Once ingested, that row is a historical fact. You cannot go back and change `plan` on an event that already landed — correcting it means deleting the affected events and re-importing them. That immutability is the point: an event property records what was true *when the thing happened*, which is exactly what time-series analysis needs. Every breakdown, filter and funnel step property in Mixpanel can operate on event properties. ## Profile properties Profile properties are written through the `people` API and stored on the user document keyed by `distinct_id`: ```javascript mixpanel.people.set({ plan: 'pro', $email: '[email protected]' }); mixpanel.people.set_once({ signup_date: '2026-01-14' }); mixpanel.people.increment('songs_played', 1); ``` `set` overwrites; `set_once` writes only if the key is absent; `increment` and `append` mutate numerically or as a list. There is one current value per key — Mixpanel does not keep a history of previous profile values for you. The consequence trips people up constantly: if you segment a funnel from six months ago by the profile property `plan`, every one of those old events is bucketed by the plan the user is on *right now*. Users who upgraded since then silently move between buckets, and the report is not reproducible over time. Profile properties are the right home for descriptive attributes you want to filter the *current* population by (email, country, account owner), and for values used by messaging and cohort definitions. ## Super properties Super properties bridge the gap. `mixpanel.register({ plan: 'pro' })` writes the key into client-side storage (a cookie or local storage in the JS library) and the library merges it into the properties of every event tracked afterwards from that browser. `register_once` sets it only if not already present — the usual way to pin a first-touch attribution value. `unregister` removes one. This gives you point-in-time correctness without threading the same argument through every call site: you register `plan` at login, and each subsequent event carries the plan as it was when the event fired. Because the storage is per-browser, super properties do not follow the user across devices, do not exist for server-side events, and are lost when site data is cleared — so re-register them from your own application state on every page load rather than assuming they persist. ## Reserved properties Keys prefixed with `$` are Mixpanel's reserved namespace — `$email`, `$name`, `$phone`, `$city`, `$browser` and so on. Some are populated automatically by the client library from the request context; some (like `$email`) are meaningful to Mixpanel's own features and should be used rather than a custom `email` key. Do not invent new `$`-prefixed names of your own. ## Choosing between them in practice Ask one question of every attribute: *do I need to know its value at the time of the event, or only now?* Anything you will slice history by — plan tier, experiment variant, locale at time of use, feature-flag state — goes on the event, usually via a super property so you register it once. Anything that describes the user as they are today — contact details, current lifecycle stage, an aggregate counter — belongs on the profile. Attributes you need both ways get written twice, deliberately, and that duplication is normal and correct. On the server side there are no super properties: your tracking code must attach the same context explicitly to each event payload, which is a good reason to build a small wrapper rather than calling the API directly from twenty places.
- A PM wants last quarter's funnel broken down by the plan the user was on at the time. What had to be true when the events were tracked?The plan must have been on the events themselves — either passed into each `track` call or registered as a super property so the library attached it. If plan only exists as a profile property, the breakdown uses today's value for all historical events and cannot be reconstructed retroactively.
- What happens to super properties when a user clears site data or opens the product on a second device?They disappear, because the JS library persists them in browser storage tied to that device. The safe pattern is to re-register the values from your own application state on every page load after authentication, so a cleared browser or a new device converges to the same set instead of tracking events without them.
- Why use $email rather than a custom email property on a profile?`$`-prefixed keys are Mixpanel's reserved namespace, and some product features and integrations look for them specifically. Using `$email` makes the value discoverable to those features; a custom `email` key is just an opaque string. You should not, however, invent your own `$`-prefixed keys.
An event property is a photograph taken at the moment; a profile property is a caption you can rewrite whenever you like — and rewriting it changes what every old photograph appears to say.
saying these in an interview costs you the question
- Believes Mixpanel keeps a history of past profile property values
- Uses people.set for values needed to segment historical events
- Thinks super properties are stored server-side against the user
- Assumes event properties can be edited after ingestion
- Calls track on every attribute change instead of updating the profile