Splitting Traffic Stay organized with collections Save and categorize content based on your preferences.
Region ID
TheREGION_ID is an abbreviated code that Google assignsbased on the region you select when you create your app. The code does notcorrespond to a country or province, even though some region IDs may appearsimilar to commonly used country and province codes. For apps created after February 2020,REGION_ID.r is included in App Engine URLs. For existing apps created before this date, the region ID is optional in the URL.
Learn moreabout region IDs.
You can use traffic splitting to specify a percentage distribution of trafficacross two or more of the versions within a service. Splitting traffic allowsyou to conductA/Btesting between your versions and provides control over the pace when rolling outfeatures.
Traffic splitting is applied to URLs that do not explicitly target aversion.For example, the following URLs split traffic because they target all theavailable versions within the specified service:
https://PROJECT_ID.REGION_ID.r.appspot.com- Distributes traffic to versions of thedefaultservice.https://SERVICE_ID-dot-PROJECT_ID.REGION_ID.r.appspot.com- Distributes traffic to versions ofthe[SERVICE_ID]service.
For information about how requests reach a version, seeHow Requests are Routed.
Before you begin
Before you can configure traffic to a version, ensure that your user accountincludes therequiredprivileges.
Avoiding caching issues
Before you turn on traffic splitting, you might want to account for potentialcaching problems. Caching issues can exist for any App Engine app,especially when deploying a new version. Traffic splitting often makes subtlecaching problems more apparent.
For example, assume you are splitting traffic between two versions, A and B,and some external cacheable resource changed between versions, for example, aCSS file. Now assume that a client makes a request and the response contains anexternal reference to the cached file. The local HTTP cache will retrieve thefile if it's in the cache, regardless of which version of the file is cached andwhich version of the application sent the response. The cached resourcecould be incompatible with the data that was sent in the response.
To avoid caching problems:
For dynamic resources, set both theCache-Control andExpires headers. These headers tell proxies that the resource is dynamic. It isbest to set both headers, since not all proxy servers support the HTTP/1.1
Cache-Controlheader properly.If you want more information on caching in general, seeHeader Fields inthe HTTP/1.1 RFC and theHTTP caching overview in Web Fundamentals.
For cacheable static resources that vary between versions, change theresource's URL between versions. If the static resources are served fromdifferent URLs, then both versions can happily co-exist in proxy servers andbrowser caches.
You can also have your app set theVary:Cookie header so that the uniqueness of a resource is computed by combining the cookiesand the URL for the request. However, this approach increases the burden oncache servers. There are 1000 possible values ofGOOGAPPUID, and hence 1000possible entries for each URL for your app. Depending on the load on the proxiesbetween your users and your app, this can decrease how often your app serves acached result. In addition, for the 24 hours after adding a new batch of usersto a version, those users might still see cached resources. However, usingVary: Cookie can make it easier to rename static resources that are changingbetween versions.
TheVary: Cookie technique doesn't work in all circumstances. In general, ifyour app is using cookies for other purposes, you must consider how thisaffects the burden on proxy servers. Ifcodeninja had its own cookie that had100 possible values, then the space of all possible cache entries becomes avery big number (100 * 1000 = 100,000). In the worst case, there is a uniquecookie for every user. Two common examples of this are Google Analytics(__utma) and SiteCatalyst (s_vi). In these cases, every user gets a uniquecopy, which severely degrades cache performance and can also increase thebillable instance hours consumed by your app.
Splitting traffic across multiple versions
When you have specified two or more versions for splitting, you must choosewhether to split traffic by using either a sender IP address or HTTP cookie. It'seasier to set up an IP address split, but a cookie split is more precise. Formore information, seeIP address splitting andCookie splitting.
Console
To split traffic in the Google Cloud console, go to the Versions page:
- Select one or more versions to which you want to split traffic.
- ClickSplit traffic and then specify:
- The method that you want to use for splitting traffic.
- The percentage of traffic each version should receive.
gcloud
After installing theGoogle Cloud CLI, you run the followingcommand to split traffic across multiple versions, for example:
gcloudappservicesset-traffic[MY_SERVICE]--splits[MY_VERSION1]=[VERSION1_WEIGHT],[MY_VERSION2]=[VERSION2_WEIGHT]--split-by[IP_OR_COOKIE]For details and additional options, see thegcloud app services set-traffic reference.
API
To programmatically migrate traffic, you can use the Admin API,seeMigrating and SplittingTraffic for details.
IP address splitting
If you choose to split traffic to your application by sender IP address, when theapplication receives a request, it hashes the IP address to a value between0–999, and uses that number to route the request.
IP address splitting has some significant limitations:
- Sender IP addresses are reasonably sticky, but are not permanent. Users connectingfrom cell phones might have a shifting IP address throughout a single session.Similarly, a user on a laptop might be moving from home to a cafe to work, andwill also shifting through IP addresses. As a result, the user might have aninconsistent experience with your app as their IP address changes.
- Because IP addresses are independently assigned to versions, the resultingtraffic split will differ somewhat from what you specify. Although, as yourapplication receives more traffic, the closer the actual split gets to yourtarget. For example, if you ask for 5% of traffic to be delivered to analternate version, the initial percent of traffic to the version mightactually be between 3–7% but eventually averages closer to your target 5%.
- If you need to send internal requests between apps, you should use cookiesplitting instead. Requests that are sent between apps running on Google'scloud infrastructure, originate from a small number of IP addresses which arelikely all assigned to the same version. Therefore, all internal requestsmight behave similar to requests sent from a single IP address, meaning thatthose requests are all routed to the same version. As a result, internalrequests do not closely respect the percentages that you set for your IP-basedtraffic splits. For example, if you set a version to receive 1% of all thetraffic to your app and the Google cloud infrastructure addresses werecoincidently assigned to that version, then the actual result might far exceed1% because all the internal requests are always routed to the assignedversion. Requests sent to your app from outside of Google's cloudinfrastructure will work as expected since they originate from a varieddistribution of IP addresses.
Cookie splitting
If you choose to split traffic to your application by cookies,the application looks in theHTTP request headerfor a cookie namedGOOGAPPUID, which contains a value between 0–999:
- If the cookie exists, the value is used to route the request.
- If there is no such cookie, the request is routed randomly.
If the response does not contain theGOOGAPPUID cookie, the app firstadds theGOOGAPPUID cookie with a random value between 0–999 beforeit is sent.
Using cookies to split traffic makes it easier to accurately assign users toversions. The precision for traffic routing can reach as close as 0.1% to thetarget split. Although, cookie splitting has the following limitations:
If you are writing a mobile app or running a desktop client, it needs tomanage the
GOOGAPPUIDcookies. For example, when aSet-Cookieresponseheader is used, you must store the cookie and include it with each subsequentrequest. Browser-based apps already manage cookies in this way automatically.Splitting internal requests requires extra work. All user requests that aresent from within Google's cloud infrastructure, require that you forward theuser's cookie with each request. For example, you must forward the user'scookie in requests sent from your app to another app, or to itself. Note thatit is not recommended to send internal requests if those requests don'toriginate from a user.
Disabling traffic splitting
To disable traffic splitting, youmigrate all traffic to a singleversion.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-15 UTC.