- Custom metrics can have four scopes: hit (single interaction), session (full visit), user (cross-session identity), and product (e-commerce item-level)
- Session-scoped metrics are the most practical for behavioral analytics—they describe the entire visit context (plan tier, role, experiment group)
- In Inspectlet, custom metrics are implemented via session tagging:
__insp.push(['tagSession', {key: value}]) - Tagged sessions become searchable and filterable in the dashboard, and tag keys can be pinned as custom columns for at-a-glance comparison
- GA4/GTM events are automatically captured as session tags when Inspectlet detects a
dataLayer, no extra code required
What Are Custom Metrics?
Every analytics platform collects default data: page views, referrer, browser, device, geographic location. These metrics tell you what happened. Custom metrics tell you who it happened to and why it matters to your business.
A custom metric is any data point you define and attach to your analytics that isn't captured automatically. Examples include a user's subscription plan, the value of their shopping cart, which A/B test variant they saw, or whether they're a first-time visitor or a returning customer.
Without custom metrics, you're limited to aggregate patterns. With them, you can answer questions like "Do enterprise users rage-click the export button more than free-tier users?" or "What's the average session duration for users in experiment variant B?" The specificity transforms analytics from a reporting tool into a decision-making engine.
Understanding Metric Scopes
The concept of scope determines how long a custom metric value persists and what level of your data hierarchy it applies to. If you've ever asked "custom metrics can have which scopes?", here's the complete answer.
Hit Scope (Interaction-Level)
A hit-scoped metric applies to a single interaction—one pageview, one event, one transaction. The value exists only for that specific hit and does not carry forward. Use hit-scoped metrics when the value changes with every action.
Examples: load time for a specific page, scroll depth at the moment of a click, the response time of an API call that just completed, or the number of items visible in a search results page.
In Google Analytics (Universal Analytics), hit-scoped custom dimensions are set with each ga('send', ...) call. In GA4, all event parameters are inherently hit-scoped because GA4's data model is event-based.
Session Scope (Visit-Level)
A session-scoped metric applies to the entire visit. Once set, the value persists for all hits within that session. If you set it multiple times in the same session, the most recent value wins and is retroactively applied to the full session.
Examples: logged-in vs. anonymous, user subscription plan during this visit, A/B test variant assignment, the traffic source that initiated the session, or a customer support ticket ID the user arrived from.
Session scope is the most commonly used scope for behavioral analytics. When you're watching a session recording and want to know "what kind of user was this?", session-scoped metrics provide the answer immediately.
User Scope (Cross-Session Identity)
A user-scoped metric persists across sessions, tied to a user identity rather than a single visit. Once set, it applies to all future sessions from that user until the value changes. This scope requires a persistent user identifier (a login ID, a first-party cookie, or a device fingerprint).
Examples: lifetime customer value, account creation date, subscription tier (when it rarely changes), user role (admin vs. member), or geographic region of the account (as opposed to the session's IP-based location).
User-scoped metrics are powerful for cohort analysis but require careful handling of identity. If a user isn't logged in, you can't reliably associate session data with their user-level attributes.
Product Scope (Item-Level)
Product-scoped metrics apply to individual items within an e-commerce transaction. Each product in a cart can have its own metric values. This scope only makes sense for e-commerce enhanced measurement.
Examples: product margin percentage, inventory status at the time of purchase, product category hierarchy, or whether the item was shown as a recommendation versus a direct search result.
For session recording and behavioral analytics, session scope covers 80% of use cases. You want to describe the context of each visit—who the user is, what plan they're on, which experiment they're in—so you can filter and segment recordings. User scope handles the remaining cross-session identity needs. Hit and product scopes are more relevant for aggregate analytics platforms like GA4.
How Custom Metrics Work in Inspectlet
Inspectlet implements custom metrics through session tagging—a key-value system that attaches metadata to each recorded session. Every tag you set becomes a searchable, filterable, sortable attribute in your dashboard.
The tagSession API
The core method is tagSession, which accepts an object of key-value pairs:
__insp.push(['tagSession', {
plan: 'enterprise',
role: 'admin',
company_size: '500+'
}]);
You can call tagSession multiple times during a session. Each call merges the new keys with existing tags—it won't overwrite tags you've already set unless you reuse the same key name. This means you can tag early (on page load) with data you already know, then tag again later as more context becomes available:
// On page load — tag with what you know immediately
__insp.push(['tagSession', {
page_type: 'checkout',
cart_items: 3
}]);
// After payment completes — add order data
__insp.push(['tagSession', {
order_value: 149.99,
payment_method: 'credit_card',
coupon_used: 'SAVE20'
}]);
Nested Objects and Dot Notation
When you pass nested objects, Inspectlet automatically flattens them using dot notation. This is useful for organizing related tags into logical groups without worrying about flat naming conflicts:
__insp.push(['tagSession', {
user: {
plan: 'pro',
role: 'editor',
tenure_months: 14
},
feature: {
dark_mode: true,
beta_enabled: true
}
}]);
// Stored as:
// user.plan: pro
// user.role: editor
// user.tenure_months: 14
// feature.dark_mode: true
// feature.beta_enabled: true
Dot-notation keys are fully searchable in the dashboard. You can filter for user.plan = pro just as you would a flat key.
User Identification
To connect sessions to a persistent user identity (user scope), use the identify call:
__insp.push(['identify', 'user_83921']);
This associates the current session with a user ID and sets a cookie so future sessions from the same browser are automatically linked. In the Inspectlet dashboard, you can then view all sessions from a specific user chronologically—giving you user-scoped context without needing a separate analytics system.
Combine identify with tagSession for the most complete picture:
// After login
__insp.push(['identify', currentUser.id]);
__insp.push(['tagSession', {
plan: currentUser.plan,
role: currentUser.role,
signup_date: currentUser.createdAt
}]);
Set Up Custom Metrics in Minutes
Tag sessions with business context and instantly filter recordings by plan, role, or any custom attribute.
Common Custom Metric Recipes
Here are proven tagging patterns used by teams running Inspectlet in production.
User Plan and Role
The single most valuable tag. Lets you compare the experience of free users versus paying customers, or admins versus regular members:
__insp.push(['tagSession', {
plan: 'enterprise',
role: 'admin',
seats: 25,
billing_cycle: 'annual'
}]);
Revenue and Order Value
Attach transaction data to sessions so you can watch recordings of high-value orders and identify friction in the purchase flow:
// After successful checkout
__insp.push(['tagSession', {
order_id: 'ORD-29481',
order_value: 347.50,
item_count: 4,
is_first_purchase: true
}]);
Feature Usage Flags
Track which features a user interacted with during the session. This helps product teams understand adoption and identify usability issues with specific features:
__insp.push(['tagSession', {
used_search: true,
used_export: true,
used_bulk_edit: false,
editor_mode: 'advanced'
}]);
A/B Test Enrollment
Tag sessions with the experiment variant so you can watch recordings segmented by test group. This gives qualitative context to your quantitative A/B test results:
__insp.push(['tagSession', {
experiment: 'checkout_redesign',
variant: 'B',
experiment_id: 'exp_2847'
}]);
Inspectlet's A/B testing feature can also use session tags to trigger goals. When a tag matches a configured goal condition, the conversion is attributed to the user's variant automatically.
Error Context
When your application catches an error, tag the session so you can quickly filter to all sessions that experienced that error:
try {
await processPayment(order);
} catch (err) {
__insp.push(['tagSession', {
error: err.message,
error_code: err.code,
error_page: location.pathname
}]);
}
For a complete production error tracking workflow, see our guide to tracking JavaScript errors in production.
Marketing Attribution (UTM Parameters)
While Inspectlet captures referrer data automatically, tagging UTM parameters gives you granular campaign attribution directly in your session list:
var params = new URLSearchParams(location.search);
var utmTags = {};
['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'].forEach(function(key) {
if (params.get(key)) utmTags[key] = params.get(key);
});
if (Object.keys(utmTags).length) {
__insp.push(['tagSession', utmTags]);
}
GA4 and GTM Integration
If your site uses Google Analytics 4 or Google Tag Manager, Inspectlet has a feature that saves you from duplicating your tagging work: automatic dataLayer capture.
When Inspectlet detects a dataLayer on the page, it automatically wraps dataLayer.push so that every GTM event is mirrored as a session tag, prefixed with GA:. If you're already pushing events like this:
dataLayer.push({
event: 'purchase',
transaction_id: 'T-12345',
value: 59.99,
currency: 'USD'
});
Inspectlet automatically creates session tags like GA: purchase, GA: transaction_id: T-12345, and so on. No additional configuration needed—the integration works out of the box.
If you prefer to keep your Inspectlet tags separate from your GA4 events (to avoid tag clutter), you can disable the auto-capture:
__insp.push(['disableGACapture']);
Place this call before the Inspectlet tracking script loads (or immediately after the __insp array is initialized) to prevent any dataLayer events from being captured.
GA4 event parameters are hit-scoped by definition. When Inspectlet captures them, they're promoted to session scope—the tag persists for the entire recorded session. This is intentional: when you're watching a session recording, you want to see all the events that happened during that session, not just the ones on the current page.
Using Custom Metrics in the Dashboard
Custom Columns
Once you've tagged sessions, the tag keys appear in your session list. To make a tag permanently visible without hovering or expanding each row, add it as a custom column. In the sessions list, click "Add tag key as custom column" and select the key you want. The column appears alongside default columns like duration, pages viewed, and location.
Custom columns are especially useful for at-a-glance triage. For example, adding a plan column lets you instantly see whether a frustrated user is on your free tier or your highest-paying plan—context that determines how urgently you prioritize the fix.
Filtering and Searching by Tags
Inspectlet's Magic Search lets you build pill-based filters that combine tag values with other session attributes. You can construct queries like "show me sessions where plan = enterprise AND the session contains a rage click AND the user visited the checkout page."
On the Events page, the "Tagged With" filter accepts both a key and a value, giving you precise control. Enter error_code as the key and PAYMENT_DECLINED as the value to find every session where a payment failure occurred.
Filters can be saved and shared with your team, so your support engineers can have a "high-value errors" saved filter while your product team maintains a "feature adoption" filter—same data, different lenses.
Analyzing Patterns Across Tagged Sessions
After filtering to a set of tagged sessions, look for patterns in the recordings. If you notice that plan = free users consistently abandon the upgrade page at the same step, that's a concrete, actionable finding. If variant = B users spend 40% longer on the checkout page, you have qualitative evidence to complement your A/B test numbers.
The combination of behavioral analysis with custom metric filtering is where session recording becomes genuinely powerful. You're not watching random sessions hoping to spot an issue—you're watching precisely the sessions that match your hypothesis.
Custom Metrics and A/B Testing Goals
Inspectlet's A/B testing engine can use session tags to trigger goal completions. When you define a goal with the evt type, it matches against data sent via tagSession. This means your tagging code serves double duty: it enriches your session recordings and powers your experiment measurements.
For example, if you tag sessions with {checkout_complete: true}, you can create an A/B testing goal that fires whenever that tag appears. The goal is automatically attributed to whatever experiment variant the user was assigned to, giving you conversion data segmented by variant with zero additional instrumentation.
This integration eliminates the common problem of maintaining separate tracking for your analytics and your experimentation platform. One tagSession call feeds both systems. Read more about setting up experiments in the A/B testing guide.
Best Practices
Use Consistent Naming Conventions
Adopt a naming convention early and enforce it. Inconsistent naming (userPlan vs. user_plan vs. plan) creates duplicate tags that fragment your data. Recommendations:
- Use snake_case for all tag keys:
order_value,user_role,experiment_variant - Use dot notation via nested objects for logical grouping:
user.plan,user.role,order.value - Keep values lowercase where possible:
plan: 'enterprise'notplan: 'Enterprise' - Document your tag schema in a shared spreadsheet or wiki so every developer on the team uses the same keys
Choose Appropriate Value Types
Tag values are stored as strings, but choosing the right format matters for filtering:
- Booleans: Use
true/false(not'yes'/'no'or1/0) - Numbers: Use actual numbers (
149.99) not formatted strings ('$149.99')—this enables numeric comparisons in filters - Enums: Use a fixed set of values (
'free','pro','enterprise') rather than freeform text - Dates: Use ISO 8601 format (
'2026-04-04') for consistency and sortability
Avoid Personally Identifiable Information
Never tag sessions with PII such as email addresses, full names, phone numbers, or government IDs. These create compliance risks (GDPR, CCPA) and aren't useful for behavioral analysis. Instead, use opaque identifiers:
// Bad — PII in tags
__insp.push(['tagSession', {
email: 'jane@example.com',
name: 'Jane Doe'
}]);
// Good — opaque identifiers + useful attributes
__insp.push(['identify', 'usr_83921']);
__insp.push(['tagSession', {
plan: 'enterprise',
role: 'admin',
account_age_days: 342
}]);
Tag Early, Tag Once
Set your tags as early in the session as possible. If the user's plan and role are available at page load, tag immediately. If additional context becomes available later (like a completed purchase), make a second tagSession call. But don't repeatedly set the same tags on every page navigation—tags persist for the session, so setting them once is sufficient.
Keep Cardinality Low
Avoid tags with extremely high cardinality (thousands of unique values). A tag like session_timestamp: '1712246400123' is useless for filtering because every value is unique. Good tags have dozens to hundreds of unique values at most: plan tiers, feature names, error codes, experiment variants.
Plan Limits and Optimization
Each Inspectlet plan includes a limit on the number of distinct custom metric keys you can use. This limit applies to the total number of unique tag keys across your account, not the number of times you call tagSession.
To check your current usage, visit the Custom Metrics documentation or your account settings. If you're approaching your limit, consider these optimization strategies:
- Consolidate related tags into nested objects. Five separate keys (
utm_source,utm_medium,utm_campaign,utm_term,utm_content) can become a singleutmobject with five nested properties, though each dot-notated key still counts individually - Remove deprecated tags from your codebase. Tags from old experiments or retired features waste your quota
- Use the GA auto-capture selectively. If you have dozens of GTM events, the auto-capture can consume your limit quickly. Use
disableGACaptureand manually tag only the events you need for session analysis - Audit tag usage periodically. If a tag key has never been used in a dashboard filter or search, it probably isn't worth tracking
If you consistently need more custom metric keys than your plan allows, upgrading your plan is typically the right move—teams that actively use custom metrics are getting significantly more value from their session recordings.
Frequently Asked Questions
What scope applies to custom metrics by default?
It depends on the platform. In GA4, custom metrics are hit-scoped (they apply to the event they're sent with). In Universal Analytics, the default scope is hit, but you can configure session, user, or product scope in the property settings. In Inspectlet, all session tags are session-scoped by default—they apply to the entire recorded visit—and user-scoped identity is handled separately via the identify call.
Custom metrics can have which scopes?
Custom metrics can have four scopes: hit (single interaction), session (full visit), user (cross-session, persistent), and product (individual e-commerce item). The right scope depends on what the metric describes. If the value can change within a session, use hit scope. If it describes the visit context, use session scope. If it describes the person, use user scope.
Can I change a tag value after it's been set?
Yes. Calling tagSession with the same key and a new value will overwrite the previous value for that session. The new value applies going forward; it doesn't retroactively change data already recorded. For user-level identity, calling identify with a different user ID will associate the session with the new identity.
How many tags can I add to a single session?
There is no per-session limit on the number of tags. The limit is on the number of distinct tag keys across your account, which varies by plan. Within those keys, you can tag as many sessions as you want with as many values as needed.
Do custom metric tags affect recording performance?
No. Tags are sent as lightweight HTTP requests separate from the session recording data stream. Adding tags does not increase recording size or slow down the user's browser. The tagSession call is asynchronous and non-blocking.