Skip to content
CMO & CTO
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

  • Digital Experience
    • Experience Strategy
    • Experience-Driven Commerce
    • Multi-Channel Experience
    • Personalization & Targeting
    • SEO & Performance
    • User Journey & Behavior
  • Marketing Technologies
    • Analytics & Measurement
    • Content Management Systems
    • Customer Data Platforms
    • Digital Asset Management
    • Marketing Automation
    • MarTech Stack & Strategy
    • Technology Buying & ROI
  • Software Engineering
    • Software Engineering
    • Software Architecture
    • General Software
    • Development Practices
    • Productivity & Workflow
    • Code
    • Engineering Management
    • Business of Software
    • Code
    • Digital Transformation
    • Systems Thinking
    • Technical Implementation
  • About
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

Event Taxonomies: Measuring What Matters

Posted on September 9, 2012 By Luis Fernandez

Everyone tells you to measure everything. Then you launch, stare at a flashing dashboard, and realize you do not know what to do next. That was me last week at 1 a.m. Two laptops open, coffee gone cold, and a brand new feature that was supposed to move signups. Pageviews looked pretty. Time on site was higher. Celebratory high fives were in the air. Then a blunt question during standup cut through it all. Did the feature change anything that matters? Silence.

We had clicks. We did not have meaning. That is when I went back to basics and wrote a real event taxonomy for the product. Not a wish list. A plan. What exactly are we tracking, why does each event exist, and which events show progress toward our goal. The difference was night and day. We shipped a smaller set of events and got answers we could act on. No more guessing.

This post is for the practical folks. If you are using Google Analytics, Mixpanel, or Kissmetrics, or you are rolling your own logs, the shape is the same. Name what matters. Track it the same way every time. Keep your team honest with a simple source of truth. These are analytics from a practitioner, with scars and all.

Why story comes first

Before we get technical, I want the story straight. Your product has a plot. Users arrive from a campaign, they look around, they try something, they hit a wall or they win. Your job is to record that plot in a way that lets you replay it and ask simple questions. Where did they come from. What did they try. Did they reach value. Did they come back. That is it. If your data does not answer those, it is just noise.

So the first step is to write the story in plain words on one page. Keep it short. Example. A visitor reads a blog post, clicks a call to action, starts signup, completes signup, invites a teammate, and creates a project. Each of those is a beat in the story. Each beat gets an event. Everything else is gravy.

The technical middle: build your event taxonomy

We will keep a few rules that save pain later. They look boring. They save your weekends.

  • Name events with a verb and a clear object. Example. Signup Started. Signup Completed. Invite Sent. Invite Accepted. Project Created. Video Played.
  • Use Title Case for event names. It reads well in dashboards.
  • Use snake_case for properties. Example. plan, referrer, source_campaign, device, price_cents.
  • Do not rename events once they ship. Add new events if needed. Keep the old ones for history.
  • Make identity consistent. Use the same user id in web, mobile, and back end jobs.

Here is a tiny tracking plan in JSON. Put a fuller version in a shared doc or a repo. Call it tracking_plan.md and treat it like code.

{
  "events": [
    { "name": "Signup Started", "properties": ["plan", "source_campaign", "referrer"] },
    { "name": "Signup Completed", "properties": ["plan", "source_campaign", "referrer", "user_id"] },
    { "name": "Project Created", "properties": ["project_id", "template", "collaborators_count"] },
    { "name": "Invite Sent", "properties": ["invitee_email_domain"] },
    { "name": "Invite Accepted", "properties": ["invitee_email_domain"] },
    { "name": "Billing Updated", "properties": ["plan", "price_cents", "period"] }
  ],
  "user_properties": ["user_id", "email", "created_at", "plan", "country"]
}

Google Analytics events the sane way

Google Analytics events have five fields. Category, Action, Label, Value, and nonInteraction. You can map our verb and object approach to these without losing your mind.

  • Category holds the object. Example. Signup. Video. Invite.
  • Action holds the verb. Example. Started. Completed. Played. Sent. Accepted.
  • Label holds detail. Example. referrer or template name.
  • Value holds numbers when you have them. Example. price in cents or a count.
  • nonInteraction as true for passive events that should not affect bounce rate.
<script>
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-XXXXX-Y']);

  // Signup Started
  _gaq.push(['_trackEvent', 'Signup', 'Started', document.referrer || '(direct)', 0, true]);

  // Signup Completed
  _gaq.push(['_trackEvent', 'Signup', 'Completed', 'plan=' + planName, 0, false]);

  // Video Played on Homepage Hero
  _gaq.push(['_trackEvent', 'Video', 'Played', 'Homepage Hero', 1, true]);

  // Attach a click handler example
  document.getElementById('cta-signup').onclick = function() {
    _gaq.push(['_trackEvent', 'Signup', 'Started', 'cta=header', 0, false]);
  };

  // load GA async
  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();
</script>

GA funnels are limited for events, so keep a parallel virtual pageview for top actions if you need the built in funnel. If you go that route, prefix with /events/ so they do not pollute content reports.

// optional virtual page for classic funnel views
_gaq.push(['_trackPageview', '/events/signup-started']);

Mixpanel and Kissmetrics for event first tracking

Mixpanel and Kissmetrics are built around events. This matches our plan nicely. Identify the user once you have a real id. Record the event with properties. Keep the names exactly as in your plan.

// Mixpanel example
mixpanel.init('YOUR_TOKEN');

// Identify user after signup
mixpanel.identify(userId);
mixpanel.people.set({
  '$email': userEmail,
  'plan': planName,
  'country': country
});

// Track key events
mixpanel.track('Signup Started', {
  plan: planName,
  source_campaign: getQuery('utm_campaign') || '(none)',
  referrer: document.referrer || '(direct)'
});

mixpanel.track('Signup Completed', {
  plan: planName,
  source_campaign: getQuery('utm_campaign') || '(none)',
  referrer: document.referrer || '(direct)',
  user_id: userId
});
// Kissmetrics example
var _kmq = _kmq || [];

_kmq.push(['identify', userId]);
_kmq.push(['record', 'Signup Started', {
  'plan': planName,
  'source_campaign': getQuery('utm_campaign') || '(none)',
  'referrer': document.referrer || '(direct)'
}]);

_kmq.push(['record', 'Signup Completed', {
  'plan': planName,
  'user_id': userId
}]);

If you are tracking mobile, the iOS and Android SDKs support the same shape. Keep event names and property names identical across platforms. You will thank yourself when you build a single funnel that includes app and web.

UTM hygiene and source of truth

Your story starts earlier than your homepage. Use UTM parameters on every campaign. Capture them on first touch and carry them through signup. Store them on the user profile so you can answer which campaign drove paying users, not just clicks.

// grab UTM on first visit and save to localStorage
(function() {
  var params = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
  var qp = {};
  for (var i = 0; i < params.length; i++) {
    var k = params[i], v = getQuery(k);
    if (v) { qp[k] = v; localStorage.setItem(k, v); }
  }
  window.getAttribution = function(k) {
    return localStorage.getItem(k) || '(none)';
  };
})();

When you send your Signup Completed event, include source_campaign from storage. That gives you clean attribution through to revenue.

Simple queries that answer real questions

If you have events in your database, a few queries punch above their weight. You can run these on Postgres or MySQL with a simple events table. Columns. user_id, event_name, properties as JSON, and occurred_at.

-- Funnel from Signup Started to Signup Completed
SELECT
  COUNT(DISTINCT CASE WHEN event_name = 'Signup Started' THEN user_id END) as started,
  COUNT(DISTINCT CASE WHEN event_name = 'Signup Completed' THEN user_id END) as completed,
  ROUND(
    COUNT(DISTINCT CASE WHEN event_name = 'Signup Completed' THEN user_id END)::numeric /
    NULLIF(COUNT(DISTINCT CASE WHEN event_name = 'Signup Started' THEN user_id END), 0)
    * 100, 2
  ) as conversion_rate_pct
FROM events
WHERE occurred_at >= now() - interval '30 days';
-- Day one retention for users who completed signup
WITH first_seen AS (
  SELECT user_id, MIN(occurred_at::date) AS d0
  FROM events
  WHERE event_name = 'Signup Completed'
  GROUP BY 1
)
SELECT
  COUNT(*) AS users_signed_up,
  COUNT(CASE WHEN e2.user_id IS NOT NULL THEN 1 END) AS users_returned_d1,
  ROUND(
    COUNT(CASE WHEN e2.user_id IS NOT NULL THEN 1 END)::numeric /
    NULLIF(COUNT(*), 0) * 100, 2
  ) AS d1_retention_pct
FROM first_seen f
LEFT JOIN events e2
  ON e2.user_id = f.user_id
  AND e2.occurred_at::date = f.d0 + INTERVAL '1 day';

These answer the boring but critical questions. Did people finish signup. Did they come back the next day. If your dashboard cannot answer those two, stop and fix your taxonomy.

Manager view: measure what moves the business

If you run a team, your job is to connect work with outcomes. The easiest trap is vanity metrics. Pageviews, raw signups, and likes are fun to show. They rarely pay the bills. Set one north star metric that maps to value. Example. Active projects created per week. Orders shipped per user. Minutes of content consumed by signed in users. Then choose the three or four events that ladder into that metric.

  • Activation. The first moment a user gets value. Example. Project Created. Playlist Saved. File Synced.
  • Retention. Repeat value. Example. Project Updated. File Synced On Day Seven. Video Played by a signed in user.
  • Revenue. Money in. Example. Billing Updated. Subscription Renewed. Upgrade Completed.
  • Referral. Growth loops. Example. Invite Sent. Invite Accepted.

Every project should name which of those it moves. Then track the two or three events that prove it. Less is more here. Your dashboard becomes a scoreboard instead of a Christmas tree.

Also, be picky with definitions. What is an active user for you. Do not copy someone else. If value only happens when a user creates at least one project and invites a teammate, then make that your activation. Write the SQL and pin it. Old numbers will look smaller. They will also be real.

Finally, create a single source of truth. One tracking plan doc in your repo. One funnel chart linked from your wiki. One spreadsheet for weekly review. Keep event names frozen. Add comments when you change behavior. When marketing starts a new campaign, add the UTM pattern to the doc. When mobile ships a new event, add it and mirror it on web. This saves a ton of time.

Quality checks that keep you sane

  • Staging first. Ship events to a staging project with a distinct token or UA id. Clear them weekly.
  • Console check. Open the network tab and confirm payloads and property names. Screenshots or it did not happen.
  • Sampling check. GA samples reports with high volume. For critical funnels, keep a second system like Mixpanel or a simple events table.
  • Backfill path. If your signup happens server side, send a server event too. That closes gaps when the browser dies mid flow.

When this routine becomes muscle memory, you can move fast without breaking trust in your data.

Your 48 hour challenge

If you made it this far, here is a short and punchy plan to fix your tracking in two days. No new tools needed. Just clarity.

  • Write the story. One page. From first visit to value to return visit.
  • Pick five core events. Use verb and object. Title Case. No fluff.
  • Define properties. For each event, list three to five properties. Keep names in snake_case.
  • Wire it. Add tracking to the product with GA or Mixpanel or Kissmetrics. Ship to staging first.
  • QA with real clicks. Click through your own funnel. Check the network tab and the vendor live view.
  • Publish the plan. Create tracking_plan.md in your repo. Link it in your wiki.
  • Build one funnel and one retention chart. Share the links with the team.
  • Decide one change. Pick a product or marketing change based on what you saw. Ship it.

Here is a tiny snippet you can paste in the console of your site to sanity check event fires while you click around.

// Console helper to spy on Mixpanel and GA events
(function() {
  var log = function() {
    if (window.console && console.log) console.log.apply(console, arguments);
  };

  if (window.mixpanel) {
    var orig = mixpanel.track;
    mixpanel.track = function(name, props) {
      log('[mixpanel]', name, props || {});
      return orig.apply(mixpanel, arguments);
    };
  }

  if (window._gaq) {
    var origPush = _gaq.push;
    _gaq.push = function(args) {
      if (args && args[0] === '_trackEvent') {
        log('[ga event]', args);
      }
      return origPush.apply(_gaq, arguments);
    };
  }
})();

One more tip. Keep a short list of banished words in your team. Words like engagement and active and quality can mean anything. Replace them with the actual event names or with a clear SQL. You will speed up meetings by a mile.

This week tech headlines are buzzing with product launches and rumor mills. It is easy to get caught chasing shiny things. Do not forget the simple stuff. Clear names. Honest metrics. A tracking plan that a new teammate can read in five minutes. That is how you measure what matters.

SEO corner. If you are searching for how to set up an event taxonomy for analytics, how to pick metrics that matter, how to design event tracking for Google Analytics, Mixpanel, or Kissmetrics, or how to build funnels and cohort analysis with clean UTM parameters, bookmark this and start with the five core events. Your future self will thank you.

General Software Software Engineering

Post navigation

Previous post
Next post
  • Digital Experience (94)
    • Experience Strategy (19)
    • Experience-Driven Commerce (5)
    • Multi-Channel Experience (9)
    • Personalization & Targeting (21)
    • SEO & Performance (10)
  • Marketing Technologies (92)
    • Analytics & Measurement (14)
    • Content Management Systems (45)
    • Customer Data Platforms (4)
    • Digital Asset Management (8)
    • Marketing Automation (6)
    • MarTech Stack & Strategy (10)
    • Technology Buying & ROI (3)
  • Software Engineering (310)
    • Business of Software (20)
    • Code (30)
    • Development Practices (52)
    • Digital Transformation (21)
    • Engineering Management (25)
    • General Software (82)
    • Productivity & Workflow (30)
    • Software Architecture (85)
    • Technical Implementation (23)
  • 2025 (12)
  • 2024 (8)
  • 2023 (18)
  • 2022 (13)
  • 2021 (3)
  • 2020 (8)
  • 2019 (8)
  • 2018 (23)
  • 2017 (17)
  • 2016 (40)
  • 2015 (37)
  • 2014 (25)
  • 2013 (28)
  • 2012 (24)
  • 2011 (30)
  • 2010 (42)
  • 2009 (25)
  • 2008 (13)
  • 2007 (33)
  • 2006 (26)

Ab Testing Adobe Adobe Analytics Adobe Target AEM agile-methodologies Analytics architecture-patterns CDP CMS coding-practices content-marketing Content Supply Chain Conversion Optimization Core Web Vitals customer-education Customer Data Platform Customer Experience Customer Journey DAM Data Layer Data Unification documentation DXP Individualization java Martech metrics mobile-development Mobile First Multichannel Omnichannel Personalization product-strategy project-management Responsive Design Search Engine Optimization Segmentation seo spring Targeting Tracking user-experience User Journey web-development

©2025 CMO & CTO | WordPress Theme by SuperbThemes