Optimizely provides a wide range of integrations with a variety of analytics platforms. When the integration is turned on and is implemented correctly, you can reasonably expect to see similar unique users in both Optimizely and your chosen analytics platform. Please note small variances are normal due to differences in what constitutes a “unique visitor” between platforms.


For more information, see our implementation guides to:

When implementing these platforms, you may notice some issues or discrepancies, such as:

  • The data you see in Optimizely doesn’t match what you see in your analytics platform
  • You don’t see data from Optimizely being passed into your analytics platform

If you see large discrepancies between Optimizely and your analytics platform, you are either dealing with an implementation issue or a data issue. In other words, either the implementation is not set up correctly or you are comparing disparate sets of data.

To rule out implementation issues, please check our support documents for your chosen analytics platform and follow the advice included.

Comparing reports in Optimizely and your analytics platform

If you’ve ruled out implementation issues, you may be encountering a data issue. 

When you compare reports in Optimizely and your analytics platform, we strongly recommend integrating the two platforms. Why? This way, we can ensure that your analytics reports will be filtered by visitors who have been bucketed into an Optimizely experiment, and we are able to ensure that the scope of visitors that are coming into either platform are the same.

Even once integrated, metrics may not look the same across Optimizely and your analytics platform.

Optimizely and your analytics platform are both optimized to look at different metrics. When you integrate the two, you can ensure that only visitors from an Optimizely experiment enter a certain custom report.

But the metrics you see in your analytics platform will look different from Optimizely’s Results page. Namely:

  • All Optimizely looks at is unique visitors. Why? Because Optimizely helps you understand how often a visitor converted, regardless of number of pageviews, etc.
  • Your analytics platform (Google Analytics, for example) can count session, pageviews, unique pageviews, entrances and other metrics. 

For example, the same visitor may visit your Optimizely experiment multiple times. That visitor may come back to the experiment after 30 minutes, triggering 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 doesn't.

If this distinction doesn't help you reconcile the data, then check these other common sources of discrepancies:

  • Is your Optimizely experiment running? Our analytics integrations collect data only when experiments are running on the page.
  • Are you tracking visitors to exactly the same set of URLs in both Optimizely and your analytics platform? For example, if your analytics platform tracks visitors sitewide but your Optimizely experiment is only running on your landing page, you’ll see higher numbers in your analytics platform.
  • Are you filtering which types of visitors are shown in Optimizely and your chosen analytics platform in the same way? For example, if you have an audience which excludes mobile visitors to your Optimizely experiment, but you are not filtering your data accordingly in your analytics platform, differences will naturally occur.
  • Are you filtering using a custom date range? If so, please be aware that certain platforms display visitors across custom date ranges in different manners. Optimizely will display only new visitors to your experiment on the dates selected, whereas other platforms will 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 on user-level scope. What this means is that all conversions and visitors are counted throughout the lifetime of your experiment rather than on a session basis. Some analytics platforms count conversions or visitors on a per session basis.
  • Does your traffic allocation match in both platforms?

As important as it is to maintain the scope of visitors measured across platforms, it is equally important to be aware of the metrics you are adding to your analytics platform.

Example: The “user” metric in Google Analytics is closest to the definition of a “unique visitor” in Optimizely.

If you believe you have repeat visitors to your site, or that people linger on your pages for longer than 30 minutes, add this metric to your report in GA so that you can corroborate your GA data with Optimizely as best as possible.

We include these defintions for you to understand what you are comparing your data in 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)
  • Pageviews (GA): A count of each time that a visitor loads -- and views -- a particular page. Each time that a page is loaded, the Google Analytics code embedded in the page’s code counts the instance. These are then totaled to provide a picture of the popularity of any specific page. The generic pageview count will include every time a page is loaded, including reloads by the same visitor.
  • Sessions (GA): A session includes visits to a site and the pages loaded in a specific period. Google Analytics sets sessions to expire after 30 minutes of inactivity, although an Analytics administrator can change this timeout length in the Admin panel to anywhere between one minute to four hours.
  • Unique Pageviews (GA): The unique pageview is different from the general pageview. As the name implies, the count only includes new page views during a single session. Instead of counting every time the page was loaded, the unique pageview is the number of sessions over a selected period of time that the page was viewed at least once. Page reloads are not counted in this number, so it will always be equal or less than the number of overall pageviews.

Google Analytics Classic

In Google Analytics Classic, custom variable slots are used to pass information along with a tracking call to specify additional information about the visitor. The Optimizely GA integration utilizes one of these custom variable slots to pass along the Experiment Name and Variation Name that 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 value and sends it along with the tracking call to GA's servers.

This integration allows you to do both of the following:

  • 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

Start by checking the following:

  • The GA tracking code must be placed at the bottom of the <head> section of your pages. Google Analytics integration will not function properly unless the Optimizely Snippet is above the GA snippet.
  • Optimizely makes use of Custom Variables for GA Classic Integration, which are limited to 5 slots per tracking call. For Universal Analytics (UA), we use Custom Dimensions. Make sure that the slot number you’re using for an Optimizely experiment is not in use by another experiment or by other tracking activities. Otherwise, the experiment names/variations 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

If those appear correct, the next few sections will help you troubleshoot the Google Analytics integration, whether you’re using a standard implementation or a customized one.

You see more unique visitors in GA than in Optimizely

Affects: Google Analytics Classic

Does this look like your issue? If not, move on to the next section:

  • Your data in GA Classic does not match Optimizely.
  • You see higher unique visitors in GA than Optimizely.
  • 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.

The workaround to make this work is to call _setDomainName before Optimizely sets the customVar. You can update the code like this:

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

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

You see more unique visitors in Optimizely than GA

Affects: Google Analytics Classic

Root cause:

The Optimizely Snippet is position lower than (but often close to) the GA snippet. The GA snippet loads asynchronously, which means that  sometimes Optimizely manages to load prior to GA and set the customVar, but most times it does not and the GA data is fired off before Optimizely can set the customVar.


Place the Optimizely Snippet above the GA snippet. 

You customized the JS object (_gaq) and now custom variables aren’t being set

By default, GA uses a JavaScript object on the page called _gaq, which is simply 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 _gaq and trust GA to find it and send it off 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 after Optimizely runs, preventing the Optimizely integration value from being passed to GA.

Because Optimizely runs first and creates _gaq, it's very important for any custom implementation of GA to make sure it checks for the existence of _gaq before it runs, and if _gaq exists (because Optimizely created it and added a custom variable), make sure to include that value when the custom implementation runs.

The line of code to do that looks like this:

var _gaq = _gaq || [];

This effectively says:

"If _gaq has already been declared on the page, use that array. Otherwise, set _gaq to be an empty array and proceed"

Google Analytics Classic OR Universal Analytics

Google Universal Analytics functions similarly to the Google Analytics Classic integration, except that custom dimensions are used to pass information along with a tracking call to specify additional information about the visitor. Google Universal Analytics Integration also requires that you add a tracking call to your page:

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

The next few sections describe problems that can occur with either the Google Universal Analytics integration, or the Google Analytics Classic integration.

You only see visits to a limited number of pages

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

Does this look like your issue? If not, move on to the next section:

  • You see visits only to a limited set of pages on your site.
  • Visitor counts between Optimizely and GA/UA don’t match up.

Root cause:

You are setting a leading period or www. when calling _setDomainName. This leads to an additional set of cookies being created. Make sure that if you have the setDomainName function call on your page it is not using a leading period.

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

Google Analytics uses something called a "domain hash" (literally, 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 causes this cookie to get overwritten and this could have a negative impact on your referrers and your bounce rate in GA.

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

If you don't add a leading period or subdomain, your root www domain gets a "domain hash" that is equivalent to http://mysite.com. However, if you add the leading period, the "domain hash" changes. None of your returning visitors will have a matching domain hash. So, when they enter your site, Google Analytics doesn't see a matching set of cookies with the correct domain hash and creates a new visitor ID, and all your traffic since the change is totally cut off from the traffic before the change.

You can "recover" the old cookies by switching to using no leading period. If you do so, you'll lose the cookies since you've made the change, though.


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

If you can’t use that solution, 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 Experiment JavaScript or even in the variation code:

/* _optimizely_evaluate=force /
window._gas = window._gas || [];
window._gas.push(['_setDomainName', 'www.mimco.com.au'])>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 avoid having session information overwritten.

If you are curious to know more about tracking across domains and subdomains with GA, please read Google's reference article or this article on GA subdomain problems. 

You see visitors on the Optimizely Results page but no data in GA

Does this look like your issue? If not, move on to the next section:

  • You see visitors and conversions on the Optimizely Results Page, but...
  • You don’t see these being passed through to GA

Affects: Google Analytics Classic and Universal 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 situated in the correct position on the page.


  1. Make sure that the GA/UA integration is enabled on your Optimizely Home page, by going to the Integrations tab and then turning the appropriate integration (Google Analytics or Universal Analytics) on.
  2. Within each experiment where you want to track data, go to the Options menu > Integrations > Google Analytics or Universal Analytics. Make sure that the box to track the 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, above the Google Analytics tracking call.

Experiment name is truncated in GA report

Affects: Google Analytics Classic and Google Universal Analytics

In this case, you may see that the experiment name is truncated or cut off, or that multivariate experiment names are getting cut off or separated with a tilde (~).

Root Cause:

Experiment titles will appear as Optimizely_[experiment title] and 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 4 variation titles will each be truncated and then joined with a tilde (~), such as blue~green~purpl~red

Why is this a problem? If variations have the same first four characters, the identical string will be passed as variation name to Google Analytics and therefore GA will interpret various combinations of variations as identical. To fix, update the variations names so the first four characters are unique.

Counts from a traffic source of direct or referral are too high

Affects: Redirect experiments in Google Analytics Classic and Google Universal Analytics

If you are running a redirect experiment, you may see that your counts for a traffic source of organic (search) are too low, and counts for direct and/or referral are too high.

Root Cause:

When a redirect takes place in Optimizely with the Classic or Universal Analytics integration enabled, we currently grab the document.referrer value and call the _setReferrerOverride(); function for Classic and the ga('set','referrer'); function for Universal in order to maintain the original referrer. This works great on landing pages; however if there is a redirect on any page deeper into your site this strips the visitor's original session referrer and makes it the immediately preceding page. This will inflate your Classic, Universal, and/or AdWords reports' direct and/or referral traffic source.


Implement this code linked on Github so that it runs on every page load above the Optimizely snippet. On the initial landing page, this code will grab the session's initial referrer and set it to a cookie. This cookie persists through the user's navigation on your site. When the user is redirected on a non-landing page as part of an Optimizely experiment, this code will determine if the existing session's referrer should be preserved, or if it should be updated to document.referrer. Then the code sends the appropriate referrer to Classic or Universal Analytics. As a result, the original traffic source is persistent.

Please be sure to note the implementation instructions at the top of the code.

Advanced Troubleshooting

If you're still having an issue with your Optimizely GA integration, there are a few technical details that may help you investigate what’s going on.

Check The Code

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

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

Here’s what the parameters indicate:

  • _setCustomVar: Sets the custom variable in GA
  • /*SLOT*/ 5: Sets a specific custom slot in GA (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 is able to make the _setCustomVar call immediately, as this is safe to do as described above. 

However, if you are loading Optimizely asynchronously, there is a potential for the_setCustomVar call to happen after the GA tracking call is sent off, which would prevent the integration from working correctly.

In this case, it is best to delay the GA tracking call until after Optimizely has finished loading, most commonly done with a callback function that waits to be triggered by another script finishing.

Additionally, consider using the holdEvents and sendEvents JavaScript APIs to control the timing of Optimizely's event logging to align it with Google Analytics tracking. Learn more about implementing this solution.

Check for Redirect Experiments

If _setCustomVar is not set on the tracking call for a redirect variation, please make sure that the redirect variation has the _optimizely_redirect comment as the first line in the variation code (<edit code> box section) to indicate a redirect:

/* _optimizely_redirect=http://custom */