You can integrate Optimizely with a variety of commonly used analytics platforms. After you set up an integration and implement it correctly, you can expect to see similar counts of unique users in Optimizely and your chosen analytics platform.


For more information, see our implementation guides:

When working with integrations, you may notice issues or discrepancies, such as:

  • The data you see in Optimizely doesn’t match the data you see in your analytics platform

  • You don’t see data from Optimizely being passed into your analytics platform

Small variations in unique user counts are normal, even if your integration is set up properly. This is because different platforms often define “unique visitor” differently.

However, larger discrepancies are usually due to an implementation issue or a data issue: either the implementation is not set up correctly, or you are comparing disparate sets of data.

To rule out implementation issues, check our support articles for your chosen analytics platform. If you’ve ruled out implementation issues, you may be encountering a data issue. For help with data issues, please read on.

Compare reports in Optimizely and your analytics platform

We strongly recommend integrating Optimizely and your analytics platform. This way, your analytics reports will be filtered by visitors who have been bucketed into an Optimizely experiment, and both reports will track the same group of visitors.

Remember that Optimizely and your analytics platform are each optimized for different metrics. When you integrate the two, you can ensure that only visitors from an Optimizely experiment appear in a particular custom report. However, the metrics you see in your analytics platform will look different from Optimizely’s Results page. In particular, Optimizely looks only at unique visitors, while your analytics platform can count session, pageviews, unique pageviews, entrances, and other metrics. 

For example, a single visitor may visit your Optimizely experiment several times. Each time she does, she will trigger another unique pageview and another session. In Optimizely, you’ll still see this as one visitor. In other words, Optimizely deduplicates visitors and conversions. Your analytics platform probably does not deduplicate visitors and conversions.

In many cases, this difference in behavior between platforms causes the discrepancies you may see in unique visitor count. If not, consider these other common sources of discrepancies:

  • Is your Optimizely experiment running? Analytics integrations collect data only when experiments are running on the page.

  • Are you tracking visitors to the same set of URLs in both Optimizely and your analytics platform? For example, if your analytics platform tracks visitors site-wide but your Optimizely experiment is only running on your landing page, you’ll see higher visitor counts in your analytics platform.

  • Are you filtering the types of visitors shown in Optimizely and your chosen analytics platform in the same way? For example, if you have an audience that excludes mobile visitors to your Optimizely experiment, but you are not using an equivalent filter on your analytics platform, you will almost certainly see significant visitor count differences between the two.

  • Are you filtering using a custom date range? Certain platforms display visitors across custom date ranges in different ways. Optimizely displays only new visitors to your experiment on the dates selected, whereas other platforms may show you both new and returning visitors on the dates selected.

  • Are you looking at session-based or user-based metrics in your analytics platforms? By default, Optimizely visitors and conversions are counted at the user level. This means that all visitors and conversions are counted throughout the lifetime of your experiment rather than on a per-session basis. Some analytics platforms count visitors or conversions on a per-session basis instead.

  • Does your traffic allocation match in Optimizely and your analytics platform? Allocating traffic differently between platforms is a common source of data discrepancies.

Metric definitions

These definitions may help you understand how your data aligns between Optimizely and Google Analytics:

  • Unique visitors (Optimizely): The number of unique visitors who were exposed to your experiment (this is based on visitors who received the optimizelyEndUserID cookie).

  • User (Google Analytics): The metric that is the closest match to Optimizely's unique visitors metric. If you believe you have repeat visitors to your site, be sure to add the "user" metric to your report in Google Analytics so you can align your analytics data with your Optimizely data as closely as possible.

  • Pageviews (Google Analytics): A count of each time a visitor loads and views a particular page. Each time a page loads, the Google Analytics code embedded within the page counts the instance. These instances are then summed to describe the total traffic for any specific page. The generic pageview count will include every time a page is loaded, including reloads by the same visitor.

  • Sessions (Google Analytics): A session includes visits to a site and the pages loaded in a specific period. Google Analytics sessions expire after 30 minutes of inactivity by default, although a Google Analytics administrator can set the expiration to any value between 1 minute and 4 hours.

  • Unique pageviews (Google Analytics): A pageview count that only includes new pageviews during a single session. Page reloads are not counted in the "unique pageview" metric, so it will always be equal to or less than the number of overall pageviews. Unique pageviews are different from the general "pageviews" metric in Google Analytics (described above).

Google Analytics Classic (GA) vs. Universal Analytics (UA)

In GA, custom variable slots are used to pass information with a tracking call to specify additional information about the visitor. The Optimizely-GA integration uses one of these custom variable slots to pass along the experiment name and variation name the visitor is currently bucketed into, if any. For example, a custom variable slot might contain a value like this:


When Optimizely runs at the top of your page, it immediately adds this custom value to the _gaq object (which is the default GA object on your page). When the GA code runs later on the page, it picks up this custom value and sends it with the tracking call to GA's servers.

This type of integration allows you to:

  • Use all your existing reports in GA

  • Separate each report by the contents of the custom variable slot, showing you a different row of data for each variation used in your experiment

UA takes a similar approach, except that custom dimensions are used to pass this information. A UA integration also requires you to add a tracking call to your page:

// Optimizely Universal Analytics Integration
 window.optimizely = window.optimizely || [];

Initial troubleshooting for data issues

When troubleshooting data issues in Google Analytics integrations, start by checking the following:

  • Make sure that the slot number you’re using for an Optimizely experiment is not in use by another experiment or other tracking activities. Otherwise, the experiment and variation names may overwrite each other.

  • Make sure that you are using the gaq object, not the older gat object, to make the tracking call. Only pages that use _gaq are currently supported.

Further troubleshooting for data issues

If the three initial troubleshooting items appear correct, the next sections will help you troubleshoot your GA or UA integration, whether you’re using a standard or customized implementation.

Issue: You see more unique visitors in Google Analytics than in Optimizely (GA)

Affects: Google Analytics Classic

Description: Your data in GA does not match Optimizely, you see higher unique visitors in GA than Optimizely, and the problem corrects itself when the Optimizely experiment is paused.

Root cause: The experiment runs on a subdomain, and you are calling _setDomainName after the snippet is loaded. Thus, when setting the customVar, the cookies are created on the wrong domain.

To make this work, call _setDomainName before Optimizely sets the customVar. Here's how to update the code:

window._gaq = window._gaq || [];
window._gaq.push(['_setAccount', 'UA-29010521-1']);
window._gaq.push(['_setDomainName', '']);
<script src="//"></script>

The section below, you only see visits to a limited number of pages, describes a related issue, also dealing with _setDomainName.

Issue: You see more unique visitors in Optimizely than Google Analytics (GA)

Affects: Google Analytics Classic

Root cause: The Optimizely snippet is positioned after the GA snippet in the page code. As a result, the GA snippet loads asynchronously, which means that although Optimizely sometimes manages to load prior to GA and set the customVar, most of the time it does not. GA data is then fired off before Optimizely can set the customVar.

Solution: Place the Optimizely snippet before the GA snippet in the page code. 

Issue: You customized the JavaScript object _gaq and now custom variables aren’t being set (GA)

Affects: Google Analytics Classic

Root cause:  By default, GA uses a JavaScript object on the page called _gaq, which is an empty array when it’s declared. Because GA always checks to see if _gaq exists before it runs, Optimizely can safely add a custom variable to it, which GA can find and send with the tracking call.

However, if your site has any type of custom implementation of GA, it’s possible for that custom code to overwrite the value that Optimizely puts in _gaq, preventing the Optimizely integration value from being passed to GA.

Solution: Your custom implementation of GA should check for the existence of _gaq before it runs. If _gaq exists (because Optimizely created it and added a custom variable), that value must be included when the custom implementation runs.

This can be accomplished with a single line of code:

var _gaq = _gaq || [];

This code effectively says, "if _gaq has already been declared on the page, use that array. Otherwise, create _gaq as an empty array and proceed."

Issue: You only see visits to a limited number of pages (GA and UA)

Affects: Google Analytics Classic (_gas, _gaq) and Universal Analytics

Symptoms: You see visits only to a limited set of pages on your site, and visitor counts between Optimizely and Google Analytics don’t match up.

Root cause: You are setting a leading period or www. when calling _setDomainName. This creates an additional set of cookies. Make sure that if you have the setDomainName function call on your page, it's not using a leading period.

For example, use .setDomainName(""); instead of .setDomainName("");

Google Analytics uses something called a domain hash (a hash of the domain or of the domain you set in _setDomainName) to prevent conflicts between cookies.

When the Optimizely integration is turned on, it uses the .setCustomVar() function. This function sets a cookie on the domain without the leading period. Calling setDomainName() with the leading period will overwrite this cookie, which could have a negative impact on your referrers and your bounce rate in Google Analytics.

If the domain hash of the domain you've configured does not match the Google Analytics cookies it finds, Google Analytics interprets this as a brand new visit (and a brand new visitor).

Here's an example: If you don't add a leading period or subdomain, your root www domain gets a domain hash that is equivalent to However, if you do add the leading period, the domain hash changes to one that will not match the domain hash of any of your returning visitors. When returning visitors enter your site, Google Analytics doesn't see a matching set of cookies with the correct domain hash, so it creates a new visitor ID. As a result, all your traffic since the hash change is separated from the traffic before the hash change.

You can recover the old cookies by switching to using no leading period. However, if you do this, you'll lose the cookies since you've made the change.

Solution: The easiest way to fix this issue is to remove the leading period or www. from your _setDomainName call.

If that isn't feasible, the workaround is to call _setDomainName before Optimizely sets the customVar so that the cookies all have the same domain hash. Depending on how you set up your tracking, you can do that by adding the following code inside custom JavaScript or even in the variation code:

/* _optimizely_evaluate=force /
window._gas = window._gas || [];
window._gas.push(['_setDomainName', ''])>br />
window._gas.push(["_setCustomVar", 4, "MI 033 Sale Page", "Variation 1", 1]); 
/ _optimizely_evaluate=safe */

Finally, make sure that the Optimizely snippet comes after your original setDomainName() call but before the trackEvent() call. This will help prevent your session information from being overwritten.

To learn more about tracking across domains and subdomains with Google Analytics, please read Google's reference article or this article on Google Analytics subdomain problems. 

Issue: You see visitors on the Optimizely Results page but no data in Google Analytics (GA and UA)

Affects: Google Analytics Classic and Universal Analytics

Symptoms: You see visitors and conversions on the Optimizely Results page, but they don’t seem to be getting passed through to Google Analytics.

Root cause: There are two possible root causes for this issue:

  • The integration may not be enabled in the experiment

  • The Optimizely snippet is not positioned correctly on the page


  1. Make sure that the appropriate integration is enabled (GA or UA) on your Optimizely home page.

  2. Within each experiment where you want to track data, navigate to Options > Integrations > Google Analytics or Universal Analytics. Make sure that Track Experiment is checked and that you’ve selected a custom variable or dimension number. Don’t worry about Custom Tracker unless you’re using a custom event tracker other than the default.

  3. Make sure that the Optimizely snippet is in the <head> tag of your page, before the Google Analytics tracking call.

Issue: Experiment name is truncated in the Google Analytics report (GA and UA)

Affects: Google Analytics Classic and Universal Analytics

Symptoms: The experiment name is truncated or cut off, or multivariate experiment names are either cut off or separated with a tilde (~).

Root Cause: Experiment titles will appear in your Google Analytics reports as Optimizely_[experiment title], truncated to 28 characters. Variation titles will be truncated to the first 24 characters. Experiment and variation titles that contain non-Latin characters may not be reported correctly in Google Analytics.

For multivariate experiments, up to four variation titles will each be truncated and joined with a tilde (~), such as blue~green~purpl~red.

Solution: If variations have the same first four characters, the identical string will be passed as variation name to Google Analytics. Therefore, Google Analytics will interpret various combinations of variations as identical. To fix this issue, update the variations' names in Optimizely so that the first four characters are unique.

Issue: Counts from a direct or referral traffic source are too high (GA and UA)

Affects: Redirect experiments in Google Analytics Classic and Universal Analytics

Symptoms: In redirect experiments, counts for an organic (search) traffic source may be too low, and counts for direct or referral traffic are too high.

Root Cause: When a redirect occurs in Optimizely with the GA or UA integration enabled, Optimizely gets the document.referrer value and calls the _setReferrerOverride(); function (for GA) or the ga('set','referrer'); function (for UA) to maintain the original referrer. This works well on landing pages, but if there is a redirect on any page deeper into your site, it strips the visitor's original session referrer and replaces it with the last page the visitor saw. This inflates the direct or referral traffic source counts for your GA, UA, and AdWords reports.

Solution: Implement this code linked on GitHub so that it runs on every page. Make sure to place it before the Optimizely snippet. On the initial landing page, this code will set the session's initial referrer to a cookie, which will persist through the visitor's navigation on your site. When the visitor is redirected on a non-landing page as part of an Optimizely experiment, this code will either preserve or update (to document.referrer) the existing session's referrer, whichever is appropriate. The code then sends the appropriate referrer to GA or UA. As a result, the original traffic source is persistent.

Follow the implementation instructions at the top of the GitHub code.

Advanced troubleshooting for data issues

If you're still having an issue with your Optimizely-Google Analytics integration, try these approaches.

Check the code

When the Optimizely snippet loads on a page, it evaluates every experiment that's running to see if it has a Google Analytics integration enabled. If it does (and the visitor is bucketed into a variation), Optimizely runs a single line of code to perform the integration, calling the _setCustomVar function in Google Analytics.

_gaq.push(["_setCustomVar", /*SLOT*/ 5, "Optimizely_HomePage", "Variation #1", /*SCOPE*/ 2]);

Here’s what the parameters mean:

  • _setCustomVar: Sets the custom variable in Google Analytics

  • /*SLOT*/ 5: Sets a specific custom slot in Google Analytics (in this case, slot 5)

  • Optimizely_HomePage: Sets the experiment name (in this case, "Optimizely Homepage")

  • Variation #1: Sets the variation name (in this case, Variation #1)

This means that if a subsequent _setCustomVar call on your site also uses slot #5, the Optimizely integration will be overwritten.

Check the timing

When the Optimizely snippet loads on a page, it can make the _setCustomVar call immediately. However, if you are loading Optimizely asynchronously, the _setCustomVar call could happen after the Google Analytics tracking call is sent, which would prevent the integration from working correctly.

In this case, it's best to delay the Google Analytics tracking call until after Optimizely has finished loading. This is most commonly done with a callback function that is triggered by the completion of another script.

You might also consider using the holdEvents and sendEvents JavaScript APIs to control the timing of Optimizely's event logging to align it with Google Analytics tracking.

Check for redirect experiments

If _setCustomVar is not set on the tracking call for a redirect variation, make sure that the redirect variation has the _optimizely_redirect comment as the first line in the variation code to indicate a redirect:

/* _optimizely_redirect=http://custom */