Best practices and tools for naming conventions of events and properties
Discrepancies in event and property names––seemingly minor (
gameStarted) as well as major (
playButtonPress)––are a surprisingly central pain point in data analytics; particularly when aiming for self-serve analytics culture.
- makes events more discoverable (which is always important, but furthermore a prerequisite for self-serve analytics culture)
- makes it easier and faster to choose names for things (which we know is notoriously difficult)
- reduces risk of duplicate versions of events names (e.g. "start game" and "game started").
Typically the following four things.
The standard sentence clause structure (opens in a new tab) the company chooses, to refer to the user action. This can for example be
[context] [object] [action](e.g.
gameplay game start)
[context] [action] [object](e.g.
gameplay start game)
The grammatical tense of the action in the event name. Typically these two:
- Past simple (e.g.
- Present simple (e.g.
- Past simple (e.g.
Set of allowed words
For example "we always use
Inconsistent event names and property names can arise either during the "data design" step or the implementation step.
What is Codegen? Codegen produces type safe code for implementing analytics. The "data designer" specifies the event structure in the Avo app, and which platforms should send the event, and then the developer who implements analytics can use Codegen per each analytics event.
For example, instead of Android calling
analytics.track("game started") and iOS calling
analytics.track("gameStarted") , they both call
Avo.gameStarted(), and the Avo function takes care of the spelling of the event and property names as they get passed into the analytics SDK.
In other words, event and property naming is abstracted entirely away from the event implementation layer, ensuring that events and properties are named the same across all platforms, teams and code bases.
Also covered in Global namespace for events and properties
As stated above, naming inconsistencies often arise either during the "data design" step, not only implementation step. This is particularly true as product organizations scale up and multiple teams contribute to the tracking plan. (It's difficult enough to remember all the events you yourself created, let alone be aware of all the events other people have created).
Avo has a global namespace to ensure that all events and properties in the tracking plan have unique names that they can be easily identified.
Having a global namespace for all events and properties significantly reduces duplicate event definitions for the same user action, and allows Avo to support people in various ways in designing better data. For example:
Avo prevents creating a duplicate event whose only difference from an existing event is the casing. Same for property names.
For example: Avo won't allow you create a
Avo nudges you if you try to create an event in a casing that contradicts your tracking plan casing convention. Same for property names.
For example: if the convention is
snake_caseand you type in
gameStartedin the event creation modal, Avo will suggest the right casing to you before you create the event:
Avo nudges you if you try to create an event with similar words as an event that already exists.
For example: if you try to create
Avo prevents you from creating properties with slightly different meaning depending on which event they are sent from.
This is a source of many confusions for the "data consumers" (analysts, PMs, whoever is digging into the data).
For example, the data consumer may be used to
player_idmeaning "id of the current player", but then all of a sudden a new event gets created with
player_idreferring to the opposing player. 🤯 The consequences are not only confusion, but also that the "normal"
player_idproperty cannot be added to the new event. With a global namespace for properties, this cannot happen*.
*_ Avo provides workarounds to bypass this, in case you have existing tracking that requires support for this. Email email@example.com for more info._
Avo enforces mutually exclusive property names for event properties and user properties.
For example, if you have a user property called
player_id, you won't be able to create an event property called
Why does this matter? Because "user properties" typically update and overwrite a state of the user (often referred to as CRUD; create, read, update, delete), while "event properties" are specific only to the event they are attached. This means if you segment data by a user property, you are segmenting by the *most-recently-known state of the user*, while if you segment data by an event property, you segment it by the *at-the-time-of-the-event state of the event*. These are typically two different states. Segmenting by them can produce vastly different results, and it can be dangerously misleading if data consumers can't distinguish between these two.
For example: Let's say there is a user property called
role, which is kept up to date to always represent the user's current role. Let's say someone creates a
payment method updatedevent with an event property
role, which represents the user's role at the time of the event. Then someone wants to verify that only admins have been able to update the payment method. If they segment
payment method updatedby the
roleuser property, instead of the
roleevent property, they will miss out on any cases where a user was able to modify the payment method as non-admin, as long as the user has been made admin since.
That's why Avo doesn't allow you to create event properties and user properties that have the same name.
In addition to the support that's built into the Avo app, the Avo review workflow enables peer review, just like for code.
The typical Avo customer has years of tracking in place when they start using Avo (and some analytics debt to pay down...). That is why Avo not only has prescriptive tools in place, but also ones that inspect and detect:
The Avo issue reporter reports events that break casing convention in your tracking plan casing:
So for example if you upload your current tracking plan in Avo, the issue reporter will highlight naming issues:
Inspector (opens in a new tab) indicates "rogue" events and properties that don't match your tracking plan
If an event or property name gets shipped that doesn't match your tracking plan*, Inspector will tell you it doesn't match your tracking plan indicate that event as "rogue" event.
For example if
msg_sentis defined in your tracking plan, but someone implements analytics for it without Avo Codegen, and ships
msgSent, then Inspector will show you those events, and indicate that they don't match the tracking plan.
*_ It's impossible to ship events or properties with names that don't match your tracking plan when you implement using Codegen, but, when companies adopt Avo, they often have multiple product teams and years of analytics tracking code in place._
- For adoption, we recommend adopting Avo team by team (not flag-day switch-over for entire company). This means: While some teams will implement with type-safe Codegen, other teams and code bases will still implement "the old way". Which means, implementation errors will slip through 😅
- For replacing old tracking code, we recommend the "scout rule"; always leaving the analytics code better than when you found it, and porting analytics code to Codegen as it makes sense.
Inspector shows you all your tracked events
This allows you to see duplicate events (and it's particularly easy for events that are in a similar location in the alphabet)
For example, if message sent is being tracked with
msgSent, you will see all of those versions and which sources they are coming from.