Splitting Traffic

You can use traffic splitting to specify a percentage distribution of traffic across two or more versions of a module. This allows you to roll out features for your app slowly over a period of time or conduct A/B testing.

Traffic splitting is applied to URLs that do not explicitly target a version, like [YOUR-PROJECT].appspot.com (which distributes traffic to versions of the default module) or [YOUR-MODULE].[YOUR-PROJECT].appspot.com, which distributes traffic to versions of [YOUR-MODULE].

For more information on modules and versions, see App Engine Modules.

Avoiding caching issues

Before you turn on traffic splitting, you may want to account for potential caching problems. Caching issues can exist for any App Engine application, especially when deploying a new version. Traffic splitting often makes subtle caching problems more apparent.

For example, assume you are splitting traffic between two versions, A and B, and some external cacheable resource (like a css file) changed between versions. Now assume the client makes a request, and the response contains an external reference to the cached file. The local HTTP cache will retrieve the file if it's in the cache - no matter which version of the file is cached and which version of the application served up the response. The cached resource could be incompatible with the data in the response.

To avoid caching problems:

  • For dynamic resources, set the Cache-Control and Expires headers. These headers tell proxies that the resource is dynamic. It is best to set both headers, since not all proxy servers support the HTTP/1.1 Cache-Control header properly.

    If you want more information on caching in general, see Header Fields in the HTTP/1.1 RFC and Document Caching in the Browser Security Handbook.

  • For cacheable static resources that vary between versions, change the resource's URL between versions. If each version of a static resource is serving from a different URL, the versions can happily co-exist in proxy servers and browser caches.

You can also have your app set the Vary: Cookie header so that the uniqueness of a resource is computed by combining the cookies and the URL for the request. However, this approach increases the burden on cache servers. There are 1000 possible values of GOOGAPPUID, and hence 1000 possible entries for each URL for your app. Depending on the load on the proxies between your users and your app, this may decrease the cache hit rate. Also note that for the 24 hours after adding a new batch of users to a version, they might still see cached resources. However, using Vary: Cookie can make it easier to rename static resources that are changing between versions.

The Vary: Cookie technique doesn't work in all circumstances. In general, if your app is using cookies for other purposes, you must consider how this affects the burden on proxy servers. If codeninja had its own cookie that had 100 possible values, then the space of all possible cache entries becomes a very big number (100 * 1000 = 100,000). In the worst case, there is a unique cookie for every user. Two common examples of this are Google Analytics (__utma) and SiteCatalyst (s_vi). In these cases, every user gets a unique copy, which severely degrades cache performance and may also increase the billable instance hours consumed by your app.

Turning on traffic splitting in the Google Cloud Platform Console

When you are ready to turn on traffic splitting, go to the Versions page in the Cloud Platform Console.
Go to the Versions page

  1. In the Traffic Splitting section, click Edit.
  2. Select two or more versions, specifying the traffic percentage assigned to each. The sum of all percentages should be 100%.

When you have specified two or more versions for splitting, you must choose whether to split the traffic by IP address or by an HTTP cookie. It's easier to set up an IP address split, but a cookie split is more precise. For more information, see IP address splitting and Cookie splitting.

After you enable traffic splitting, the percentage of traffic routed to each version is indicated on the App Engine dashboard in parenthesis.

To disable traffic splitting, select a single version from the version list and press Route all traffic.

IP address splitting

If you choose to split traffic to your application by IP address, when the application receives a request, it hashes the IP address to a value between 0–999, and uses that number to route the request.

IP address splitting has some significant limitations:

  • Because IP addresses are independently assigned to versions, the resulting traffic split will differ somewhat from what you specify. For example, if you ask for 5% of traffic to be delivered to an alternate version, the actual percent of traffic the the version might be between 3–7%. The more traffic your application receives, the more accurate the split will be.
  • IP addresses are reasonably sticky, but are not permanent. Users connecting from cell phones may have a shifting IP address throughout a single session. Similarly, a user on a laptop may be moving from home to a cafe to work, and hence also shifting through IP addresses. As a result, the user may have an inconsistent experience with your app as their IP address changes.
  • Requests sent to your app from outside of Google's cloud infrastructure will work normally. However, requests sent from your app to another app (or to itself) are not sent to a version because they all originate from the a small number of IP addresses. This applies to any traffic between apps within Google's cloud infrastructure. If you need to send requests between apps, use cookie splitting instead.

If you choose to split traffic to your application by cookies, the application looks in the HTTP request header for a cookie named GOOGAPPUID that contains a value between 0–999. If the cookie exists the number is used to route the request. If there is no such cookie the request is routed randomly - and when the response is sent the app adds a GOOGAPPUID cookie, with a random value between 0–999. (The cookie is added only when traffic split by cookie is enabled and the response does not already contain a GOOGAPPUID cookie.)

Splitting traffic using cookies makes it easier to accurately assign users to versions, which allows more precision in traffic routing (as small as 0.1%). Cookie splitting also has some limitations:

  • If you are writing a mobile app or running a desktop client, it needs to manage the GOOGAPPUID cookies. When your app server sends back a response with a Set-Cookie header, you must store the cookie and include it with each subsequent request. Browser-based apps already manage cookies in this way automatically.

  • Splitting internal requests requires extra work. Requests sent server-side from your app to another app (or to itself) can be sent to a version, but doing so requires that you forward the user's cookie with the request. Note that internal requests that don't originate from the user are not recommended for versions.

Send feedback about...

App Engine standard environment for PHP