- Optimizely Web Experimentation
- Optimizely Personalization
- Optimizely Performance Edge
- Optimizely Feature Experimentation
If your Monthly Usage Information reports more Monthly Active Users (MAUs) than expected, work through this article to identify the cause. The article covers three steps: enable bot filtering, run diagnostic queries, and use a consistent visitor ID across Optimizely products.
For background on MAUs and how each Optimizely product reports them, see Monitor monthly active users (MAUs).
Prerequisites
Before you start, gather the following access and exports so you can complete every step in this article:
- Administrator access to your Optimizely Experimentation account, so you can view the Usage dashboard.
- Feature Experimentation administrator access, to enable bot filtering for SDKs that need manual configuration, if you are using Feature Experimentation.
- A configured Experimentation Events Export, so you can run the diagnostic queries against your decision and conversion data. See Access Optimizely Experimentation Event Export data or Send Optimizely Decision and Conversion Data to your Warehouse.
The example queries in this article use Presto or Athena SQL syntax (CROSS JOIN UNNEST) to read events from S3. Adapt the syntax if you query your data with a different engine.
Diagnostic decision flow
Work through the following checks in order. Each one points you to the section that resolves it.
- Verify that bot filtering is enabled for every SDK and Web Experimentation project that sends events to Optimizely. If not, see Enable bot filtering.
- Run the Break down MAUs by client engine query from Run diagnostic queries. The result tells you where the MAUs come from.
-
Mostly from decisions – Review your
decideAPI calls. You are likely sending inconsistent or non-uniqueuserIdvalues for the same visitor. -
Mostly from conversions – Look for
trackEventcalls that fire for visitors who never enter an experiment. - Both – Review both APIs.
-
Mostly from decisions – Review your
- Confirm you use the same visitor ID across Web Experimentation and Feature Experimentation. If not, see Use a consistent visitor ID across products.
- Contact Optimizely Support if MAU overages continue after you work through the previous sections. Include the output of your diagnostic queries and a description of your visitor ID strategy.
Enable bot filtering
Bot filtering tells Optimizely to ignore traffic from user agents on a known bot list. Filtering this traffic prevents bots from inflating your MAU count.
- Bot filtering is on by default for Optimizely Web Experimentation and for the Feature Experimentation JavaScript and React SDKs.
- For all other Feature Experimentation SDKs, you must enable bot filtering manually. Set the
$opt_user_agentattribute on the user context you pass to the SDK. Then, enable bot filtering in your Feature Experimentation project settings.
For step-by-step instructions, see the following articles:
- Filter bot and spider traffic from results (Web Experimentation).
- Manage bot filtering (Feature Experimentation).
Run diagnostic queries
The four queries in this section help you locate where your MAUs are coming from. Run them against your Experimentation Events Export. In every query, replace the example timestamp range with your billing cycle start and end timestamps.
Count MAUs in a billing cycle
This query returns the same MAU number you see on the Usage dashboard. Run it first to confirm that the data in your export matches what Optimizely is billing.
SELECT
COUNT(DISTINCT visitor_id) AS MAU
FROM (
-- Select visitor_id from Decisions table within the specified date range and account
SELECT visitor_id
FROM decisions
WHERE
timestamp BETWEEN TIMESTAMP '2026-04-01 00:00:00' AND TIMESTAMP '2026-04-30 00:00:00'
UNION
-- Select visitor_id from Conversions table within the specified date range and account
SELECT visitor_id
FROM events
WHERE timestamp BETWEEN TIMESTAMP '2026-04-01 00:00:00' AND TIMESTAMP '2026-04-30 00:00:00'
) AS unique_visitors;
Break down MAUs by client engine
The client_engine column in the events export records which Optimizely product or SDK generated each event. This query groups MAUs by client_engine. The result shows which client engine drives the overage.
SELECT
client_engine,
COUNT(DISTINCT visitor_id) AS MAU
FROM (
-- Select visitor_id and client_engine from Decisions table within the specified date range and account
SELECT visitor_id, client_engine
FROM decisions
WHERE timestamp BETWEEN TIMESTAMP '2026-04-01 00:00:00' AND TIMESTAMP '2026-04-30 00:00:00'
UNION
-- Select visitor_id and client_engine from Conversions table within the specified date range and account
SELECT visitor_id, client_engine
FROM events
WHERE
timestamp BETWEEN TIMESTAMP '2026-04-01 00:00:00' AND TIMESTAMP '2026-04-30 00:00:00'
) AS unique_visitors
GROUP BY client_engine;
When you know which client engine is generating the most MAUs, audit the decide and trackEvent calls in that engine. Common issues include the following:
- Calling
decideordecideAllfor visitors who never reach an experiment. - Firing
trackEventcalls outside the flows where experiments are activated.
The total returned by this query is higher than the total in the Usage dashboard. The dashboard counts a visitor exposed to multiple client engines as one MAU. This query counts the visitor once per engine.
Verify bot filtering is enabled
This query counts the events Optimizely received with the $opt_user_agent attribute set. The query excludes the JavaScript and React SDKs because they apply bot filtering automatically. If the result is 0, you have not enabled bot filtering for your other SDKs. Return to Enable bot filtering.
-- For Decisions table
SELECT
'Decisions' AS table_name,
COUNT(*) AS row_count
FROM decisions
CROSS JOIN UNNEST(attributes) AS t (attribute)
WHERE client_engine NOT IN ('javascript-sdk', 'js', 'react-sdk')
AND attribute.name = '$opt_user_agent'
UNION ALL
-- For Conversions table
SELECT
'Conversions' AS table_name,
COUNT(*) AS row_count
FROM events
CROSS JOIN UNNEST(attributes) AS t (attribute)
WHERE client_engine NOT IN ('javascript-sdk', 'js', 'react-sdk')
AND attribute.name = '$opt_user_agent';
Identify whether MAUs come from decisions or conversions
MAUs come from two event types: decision events (the decide API) and conversion events (the trackEvent API). A decision records when an SDK evaluates an experiment for a visitor. A conversion records when a visitor takes a tracked action. Splitting the MAU count by source narrows down where to investigate.
SELECT
'Decisions' AS table_name,
COUNT(DISTINCT visitor_id) AS MAU
FROM decisions
WHERE timestamp BETWEEN TIMESTAMP '2026-04-01 00:00:00' AND TIMESTAMP '2026-04-30 00:00:00'
UNION ALL
SELECT
'Conversions' AS table_name,
COUNT(DISTINCT visitor_id) AS MAU
FROM events
WHERE timestamp BETWEEN TIMESTAMP '2026-04-01 00:00:00' AND TIMESTAMP '2026-04-30 00:00:00';
- Audit your
decideAPI calls if most MAUs come from decisions. You are likely sending inconsistent or non-uniqueuserIdvalues for the same visitor. - Look for leaked
trackEventcalls if most MAUs come from conversions. A leaked call fires for a visitor who never enters an experiment.
Use a consistent visitor ID across products
Different visitor IDs in Web Experimentation and Feature Experimentation cause Optimizely to count the same person twice (once per product). The duplicate count inflates your MAU total.
By default, the products handle visitor IDs differently:
- Web Experimentation generates its own visitor ID and stores it in the
optimizelyEndUserIdcookie. - Feature Experimentation uses the
userIdyou pass in when you create the user context.
To prevent double-counting, configure both products to use the same identifier.
- If you have an anonymous ID available on first page load, use it for both Web Experimentation and Feature Experimentation.
- If not, reuse the identifier from your analytics tool (for example, the Google Analytics
_gacookie). Optimizely cannot read client-side cookies such as_gaon the first page load.
Web Experimentation supports overriding its default visitor ID. To configure the override, see Bring your own visitor ID (BYOID).
Contact Optimizely Support
If you complete the previous three steps and your MAU count is still higher than expected, contact Optimizely Support. Include the output of the diagnostic queries and a description of your visitor ID strategy.
Article is closed for comments.