January 28, 2026

How to Instrument the Events That Actually Matter

Most teams either track nothing or track everything and drown in noise. Here's a practical framework for choosing the handful of events that answer real product questions — and how to capture them with one snippet.

How to Instrument the Events That Actually Matter

"Track everything" is useless advice when you're the one who has to read the dashboard afterward. Most teams land in one of two failure modes: they instrument nothing and fly blind, or they fire an event on every click and end up with a thousand metrics nobody trusts.

The good news is that a handful of well-chosen events answer almost every product question you actually have. Here's a framework for picking them, naming them, and capturing them without turning your codebase into a tracking maze.

Start with questions, not events

Don't open your editor and start sprinkling capture() calls. Open a doc and write down the questions you need answered. Good instrumentation is just those questions, translated into events.

Almost every question collapses into three buckets:

  • Activation — did a new user reach the moment where your product clicks? (Created their first project, sent their first message, connected their first integration.)
  • Key actions — are people doing the thing your business depends on? (Completed checkout, published a post, invited a teammate.)
  • Drop-off — where do people fall out of a flow you care about? (Started signup but never finished, added to cart but never paid.)

If an event you're about to add doesn't map to one of these, pause. It's probably noise.

Let autocapture do the boring work

Here's the part most instrumentation guides skip: you don't need a custom event for most of this. OakData's single snippet already records pageviews, clicks, web vitals, errors, and full sessions automatically. That means "which page do people leave from" and "which button gets clicked" are already answered before you write a line of code.

Reach for an explicit oak.capture() only when the event is semantic— something autocapture can't infer from a DOM element alone. A click on a button is autocaptured. The fact that the click resulted in a completed purchase, with a plan and a dollar amount attached, is a custom event. Rule of thumb: if you'd need to attach business meaning or properties to it, capture it explicitly; otherwise let autocapture and session replay cover it.

A naming convention you'll actually keep

Inconsistent names are how dashboards rot. Signup, sign_up, and userSignedUp firing in three different places turn one metric into three. Pick one convention on day one and enforce it.

The convention that ages best: object_action, lowercase, snake_case, past tense.

  • account_created — not create_account or Signup
  • checkout_completed — not completedCheckout
  • invite_sent, project_created, plan_upgraded

Past tense matters: events describe things that already happened, so checkout_completed reads correctly in a funnel where checkout_started comes first. Keep the noun first so related events sort together alphabetically.

Put the answer in the properties

An event name tells you whathappened. Properties tell you the story around it — and they're what let you slice a single event a dozen ways instead of inventing a dozen events.

Resist creating checkout_completed_pro and checkout_completed_free. Capture one event and pass the difference as a property:

oak.capture("checkout_completed", { plan: "pro", amount: 49, currency: "usd" })

Good properties to attach:

  • Categorical dimensionsyou'll want to group by — plan, source, variant, role.
  • Valuesyou'll want to sum or average — amount, item count, duration.
  • Context that explains the event later — which flow it came from, whether it was a first-time action.

What notto put in properties: high-cardinality junk like raw timestamps, full URLs, or anything personally identifying that doesn't belong in analytics. If a property has a near-infinite set of values, it won't group into anything useful.

Tie events to a person with identify

Events are far more useful once they're attached to a stable user. Call oak.identify() at login or signup so anonymous sessions stitch to a known person and follow them across devices:

oak.identify("user_8f3a", { plan: "pro", signup_source: "launch" })

This is what turns "someone completed checkout" into "a pro-plan user from the launch cohort completed checkout, two days after signing up." If you want the deeper version of how identity stitching works, that's its own topic in first-party analytics.

A starter set for a typical SaaS

You can usually cover activation, key actions, and drop-off with five to eight custom events. For a B2B SaaS, that's roughly:

  • account_created — the top of every funnel.
  • activated— your one activation moment, defined honestly (the action correlated with retention, not just "logged in").
  • project_created / invite_sent — the key actions that signal real usage.
  • checkout_started and checkout_completed — the pair that gives you a conversion rate and a drop-off point for free.
  • plan_upgraded / plan_canceled — revenue movement.

Everything else — which page, which button, where they rage-clicked — is already in autocapture. You are deliberately keeping the custom set small.

Avoid the vanity trap

Vanity events are the ones that feel productive to track but never change a decision. The test is simple: beforeyou add an event, name the decision it would inform. If you can't, skip it.

  • Total clicks on a marketing page tells you nothing — clicks toward signup tell you something.
  • "Feature viewed" on everything floods your event stream and dilutes the events that matter.
  • Counts with no denominator— "1,200 checkouts" means nothing without "out of how many starts." Instrument both sides of every funnel, or neither.

Fewer, sharper events beat exhaustive coverage every time. A dashboard with eight trusted metrics gets read. One with eighty gets ignored.

Capture once, read everywhere

Because OakData captures with one snippet and exposes everything over a REST API and MCP, you're not locked into a single dashboard. The same checkout_completed event powers a funnel chart, an API query your billing job runs, and a question you ask an agent in plain English. Instrument it well once, and every reader — human or model — gets a clean answer.

Start with three questions. Add the five events that answer them. Lean on autocapture for the rest. You can always add more later — but you'll rarely need to.


OakData auto-captures pageviews, clicks, vitals, and errors from one snippet — and lets you add the handful of custom events that actually move the needle.