Migrating and Splitting Traffic with the Admin API

Region ID

The REGION_ID is an abbreviated code that Google assigns based on the region you select when you create your app. The code does not correspond to a country or province, even though some region IDs may appear similar 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 more about region IDs.

Manage how much traffic is received by a version of your application by migrating or splitting traffic.

Traffic migration smoothly switches request routing, gradually moving traffic from the versions currently receiving traffic to one or more versions that you specify.

Traffic splitting distributes a percentage of traffic to versions of your application. You can split traffic to move 100% of traffic to a single version or to route percentages of traffic to multiple versions. Splitting traffic to two or more versions allows you to conduct A/B testing between your versions and provides control over the pace when rolling out features.

Remember: Traffic splitting is applied to URLs that do not explicitly target a version. For example, the following URLs split traffic because they target all the available versions within the specified service:

  • [MY_PROJECT_ID].[REGION_ID].r.appspot.com - Distributes traffic to versions of the default service.
  • [MY_SERVICE]-dot-[MY_PROJECT_ID].[REGION_ID].r.appspot.com - Distributes traffic to versions of the MY_SERVICE service.

The REGION_ID is an abbreviated code that Google assigns based on the region you select when you create your app. The code does not correspond to a country or province, even though some region IDs may appear similar 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.

For more information, see How Requests are Routed.

To manually perform traffic migration and splitting from the Google Cloud console, see Migrating Traffic and Splitting Traffic.

Before you begin

Migrating traffic with the Admin API behaves differently from the Google Cloud console. To migrate traffic with the Admin API, you must be able to authorize your HTTP requests and your versions must meet the traffic migration requirements:

Traffic migration (migrateTraffic=true) requirements:

  • Your user account must include the required privileges before you can configure traffic.

  • Gradual traffic migration is not supported in the App Engine flexible environment.

  • To perform a gradual traffic migration, the target versions must be located within instances that are configured for:

Migrating or splitting traffic

To migrate or split traffic between versions of your app:

  1. Authorize your HTTP requests, for example obtain an access token.

    Authorizing access to the Admin API can be accomplished with different OAuth flows depending on the needs of your API app. For more information, see Accessing the API.

  2. Use the patch method of the apps.services collection to update the configuration of your version to either migrate traffic or configure traffic splitting. The following sample HTTP PATCH request has been intentionally wrapped for readability:

    PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/
      ?updateMask=split {
        "split": {
          "shardBy": "[MY_SHARDBY_METHOD]",
          "allocations": { "[MY_APP_VERSION]": [MY_TRAFFIC_PERCENT] }
        }
      }
    

    HTTP request parameters and fields:

    • updateMask: Specifies which of the fields in the configuration to update.
    • migrateTraffic=true (optional): Specifies to migrate traffic gradually.

    • split: Defines the configuration for traffic to your versions.

      • shardBy (optional): Defines the method that is used to split traffic. Required for gradual traffic migration (migrateTraffic=true). Valid values are COOKIE or IP.
      • allocations: Defines one or more versions and the percent of traffic that is distributed to each version. The version and percentage of traffic is specified as a key:value pair. The traffic percentage is specified as a decimal fraction and must sum to 1. Example: "allocations": { "v1": 0.8, "v2": 0.2 }

    See the apps.services collection for details and the complete list of parameters and fields.

    Example HTTP requests:

    • Move all traffic to a version:

      PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split {"split": { "allocations": { "v1": 1 } } }
      
    • Migrate all traffic to v2:

      PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split&migrateTraffic=true {"split": { "shardBy": "IP", "allocations": { "v2": 1 } } }
      
    • Split 80% of traffic to version v1 and 20% to v2:

      PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split { "split": { "shardBy": "IP", "allocations": { "v1": 0.8, "v2": 0.2 } } }
      

Example: Moving traffic to another version

This example demonstrates how to move all traffic to a new version that you just deployed. For example, the server is returning errors so you've fixed the bug, deployed the new v2 version, and now want to redirect all traffic.

To move all the traffic from v1 to v2:

  1. Verify that 100% of traffic is currently being sent to the v1 version with the GET method of the apps.services collection.

    Example HTTP GET request:

    GET https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default
    

    Example cURL command:

     curl -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default
    

    Example response:

    {
      "name": "apps/[MY_PROJECT_ID]/services/default",
      "id": "default",
      "split": {
        "allocations": {
          "v1": 1
        }
      }
    }
    
  1. Update the traffic split configuration so that all traffic is moved to the new version by using the PATCH method of the apps.services collection.

    In the HTTP PATCH request, you must specify the service within your application where both versions are running, for example default. You must also include the updateMask field with the split value to specify that you are updating the traffic split configuration.

    Example HTTP PATCH request:

    PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split {"split": { "allocations": { "v2": "1" } } }
    

    Example cURL command:

    curl -X PATCH -H "Content-Type: application/json" -d "{ 'split': { 'allocations': { 'v2': '1' } } }" -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split
    

    Example response:

    {
      "name": "apps/[MY_PROJECT_ID]/operations/bdda402c-77a9-4c6d-b022-f2f69ba78420",
      "metadata": {
        "@type": "type.googleapis.com/google.appengine.v1.OperationMetadataV1",
        "insertTime": "2015-05-29T17:25:30.413Z",
        "method": "com.google.appengine.v1.Services.UpdateService",
        "target": "apps/[MY_PROJECT_ID]/services/default",
        "user": "me@example.com"
      }
    }
    
    PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split&migrateTraffic=true {"split": { "shardBy": "IP", "allocations": { "v2": "1" } } }
    
  2. Ensure that the configuration update has completed:

    1. View the status of the update operation with an HTTP GET request:

      To view the status of the operation that is performing the update, you use the GET method of the apps.operations collection along with the operation name that was returned in the HTTP response of the previous step:

      Example HTTP GET request:

      GET https://appengine.googleapis.com/v1/[OPERATION_NAME]
      

      Where [OPERATION_NAME] is the value of the name field in the response of the HTTP PATCH request that you sent in the previous step.

      If the HTTP response from the previous step includes:

      "name": "apps/[MY_PROJECT_ID]/operations/bdda402c-77a9-4c6d-b022-f2f69ba78420"
      

      Then you send the following HTTP request to view the operation status:

      GET https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/operations/bdda402c-77a9-4c6d-b022-f2f69ba78420
      

      Example cURL command:

      curl -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/operations/bdda402c-77a9-4c6d-b022-f2f69ba78420
      
    2. After the operation completes, you can view the details of the service where the version is with another HTTP GET request:

      Example HTTP GET request:

      GET https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default
      

      Example cURL command:

      curl -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default
      
  3. Optional: You can now remove the faulty v1 version from your App Engine application with an HTTP DELETE request.

    Example HTTP DELETE request:

    DELETE https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/versions/v1
    

    Example cURL command:

    curl -X DELETE -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/versions/v1
    

Example: Splitting traffic between versions

This example demonstrates how to configure traffic splitting across multiple versions of your application. For example, you just created version v2 and v3 that each include new features but you want to roll out those features slowly so that they each receive only 20% of the traffic.

  1. After deploying the v2 and v3 versions to your App Engine application, you use the HTTP PATCH request to configure the three versions so that traffic is split 60% to v1 and 20% each to v2 and v3:

    Example HTTP PATCH request:

    PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split { "split": { "shardBy": "IP", "allocations": { "v1": "0.6", "v2": "0.2", "v3": "0.2" } } }
    

    Example cURL command:

    curl -X PATCH -H "Content-Type: application/json" -d "{ 'split': { 'shardBy': 'IP', 'allocations': { 'v1': '0.6', 'v2': '0.2', 'v3': '0.2' } } }" -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split
    
  2. After you verify that the operation has completed, you can send the HTTP GET request to verify that the traffic has been split across your versions, for example:

    Example HTTP PATCH request:

    GET https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default
    

    Example cURL command:

    curl -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default
    

    Example response:

    {
      "name": "apps/[MY_PROJECT_ID]/services/default",
      "id": "default",
      "split": {
        "allocations": {
          "v1": 0.6,
          "v2": 0.2,
          "v3": 0.2
        }
      }
    }