Managing Service Quota

This page describes how to view all quota metrics and limits on a Google Cloud project for a specific service, and how to cap the quota usage for that service using a quota override. You can use Service Usage to manage quota for your projects for any service, including public Google Cloud services and private services created using Cloud Endpoints. For more information on the differences between public and private APIs and services, see Public and Private Services.

For most operational use cases, the simplest way to manage quota is to use Google Cloud Console. If you need to program against the Service Usage API, we recommend that you use one of our provided client libraries. To experiment with the API, you can follow the instructions in this guide and use the gcurl command to test the API without setting up a full application development environment.

Before you begin

To use the examples on this page, complete all steps listed in the Getting Started guide. These steps include defining gcurl, which is an authenticated alias for the standard curl command, and defining the environment variable PROJECT_NUMBER.

Be sure to familiarize yourself with the service quota model to better understand the terminology used in this tutorial.

Displaying service quota

To see all quota metrics and limits that apply to a specific consumer on a service, use the following command:

gcurl "https://serviceusage.googleapis.com/v1beta1/projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics"

The call responds with a list of metrics defined by the service, each with the list of limits on those metrics that apply to this consumer, the values for those limits, and any overrides. Here's a partial example response:


{
  "metrics": [
    ...
    {
      "name": "projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fcpus",
      "displayName": "CPUs",
      "consumerQuotaLimits": [
        {
          "name": "projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fzone",
          "unit": "1/{project}/{zone}",
          "isPrecise": true,
          "metric": "compute.googleapis.com/cpus",
          "quotaBuckets": [
            {
              "effectiveLimit": "-1",
              "defaultLimit": "-1"
            }
          ]
        },
        {
          "name": "projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion",
          "unit": "1/{project}/{region}",
          "isPrecise": true,
          "metric": "compute.googleapis.com/cpus",
          "quotaBuckets": [
            {
              "effectiveLimit": "24",
              "defaultLimit": "24"
            },
            {
              "effectiveLimit": "72",
              "defaultLimit": "72",
              "dimensions": {
                "region": "asia-northeast1"
              }
            },

            ...

            {
              "effectiveLimit": "72",
              "defaultLimit": "72",
              "dimensions": {
                "region": "australia-southeast1"
              }
            }
          ]
        }
      ],
      "metric": "compute.googleapis.com/cpus",
      "unit": "1"
    },
    ...
    {
      "name": "projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways",
      "displayName": "External VPN gateways",
      "consumerQuotaLimits": [
        {
          "name": "projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways/limits/%2Fproject",
          "unit": "1/{project}",
          "isPrecise": true,
          "metric": "compute.googleapis.com/external_vpn_gateways",
          "quotaBuckets": [
            {
              "effectiveLimit": "15",
              "defaultLimit": "15"
            }
          ]
        }
      ],
      "metric": "compute.googleapis.com/external_vpn_gateways",
      "unit": "1"
    },
    ...

Each metric in the response has a name field; to inspect quota settings for just that metric, rather than for all metrics, use its name in the URL. For the purposes of this tutorial, the environment variable METRIC_RESOURCE_NAME stores the quota metric resource name:

METRIC_RESOURCE_NAME="projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways"
gcurl "https://serviceusage.googleapis.com/v1beta1/${METRIC_RESOURCE_NAME}"

Since a specific metric resource name is given, the call returns only the information for that metric:

{
  "name": "projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways",
  "displayName": "External VPN gateways",
  "consumerQuotaLimits": [
    {
      "name": "projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways/limits/%2Fproject",
      "unit": "1/{project}",
      "isPrecise": true,
      "metric": "compute.googleapis.com/external_vpn_gateways",
      "quotaBuckets": [
        {
          "effectiveLimit": "15",
          "defaultLimit": "15"
        }
      ]
    }
  ],
  "metric": "compute.googleapis.com/external_vpn_gateways",
  "unit": "1"
}

Similarly, each limit within a metric has a name field; to inspect quota settings for just that limit on that metric, rather than for all limits on a metric or all metrics, use its name in the URL. For the purposes of this tutorial, the environment variable LIMIT_RESOURCE_NAME stores the quota limit resource name:

LIMIT_RESOURCE_NAME="projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways/limits/%2Fproject"
gcurl "https://serviceusage.googleapis.com/v1beta1/${LIMIT_RESOURCE_NAME}"

When a specific limit is given, the call returns only the information for that limit:

{
  "name": "projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways/limits/%2Fproject",
  "unit": "1/{project}",
  "isPrecise": true,
  "metric": "compute.googleapis.com/external_vpn_gateways",
  "quotaBuckets": [
    {
      "effectiveLimit": "15",
      "defaultLimit": "15"
    }
  ]
}

Creating a consumer quota override

The owner of a project may apply a consumer override to a specific quota limit on that project, to reduce the total amount of quota that the consumer can charge against that limit.

Note that a consumer override cannot increase the available quota beyond what is allowed by the service default and any existing overrides by other parties (such as the service owner or an organization's quota administrator). To increase available quota, use the Edit Quotas option on the main quota page, or ask the org admin for a quota uplift.

To identify a limit to override, first use one of the previous methods to find the quota limit of interest. Then use the name field of the quota limit to create a new consumer override on that limit. The following example is for the per-project limit of the "External VPN gateways" quota metric of the Compute Engine service:

LIMIT_RESOURCE_NAME="projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways/limits/%2Fproject"
gcurl "https://serviceusage.googleapis.com/v1beta1/${LIMIT_RESOURCE_NAME}/consumerOverrides" -d '{"overrideValue": "14"}'

When the call succeeds, it returns an operation identifier, which represents ongoing work on the server, as the quota change propagates to backend systems:

{
  "name": "operations/quf.92accba3-6530-4fc1-9a95-c1280d48a6b7"
}

To check the progress of the operation, just use its name:

OPERATION_NAME="operations/quf.92accba3-6530-4fc1-9a95-c1280d48a6b7"
gcurl "https://serviceusage.googleapis.com/v1/${OPERATION_NAME}"

If the operation succeeds, then the response message includes done: true and contains the newly created override resource. If the operation fails, then the response message includes done: true but contains error details instead of the resource.

To verify that the override was created, list all consumer overrides for the limit:

gcurl "https://serviceusage.googleapis.com/v1beta1/${LIMIT_RESOURCE_NAME}/consumerOverrides"

The newly created override should appear in the list:

{
  "overrides": [
    {
      "name": "projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways/limits/%2Fproject/consumerOverrides/Cg1RdW90YU92ZXJyaWRl",
      "overrideValue": "14"
    }
  ]
}

Creating regional or zonal quota overrides

Some quota limits are enforced on a per-region or per-zone basis; this is indicated by the presence of {region} or {zone} in the unit field of the limit. For example, a limit with the unit "1/{project}/{region}" is enforced on a per-region basis. Applying an override to such a limit changes the base quota on each region or zone. To change the quota for only a specific region or zone, add a quota dimension using the dimensions field when creating the override. For example, create a regional override on a Compute Engine regional quota limit like this:

REGIONAL_LIMIT_RESOURCE_NAME="projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion"
gcurl "https://serviceusage.googleapis.com/v1beta1/${REGIONAL_LIMIT_RESOURCE_NAME}/consumerOverrides" -d '{"overrideValue": "65", "dimensions": {"region": "southamerica-east1"} }'

To verify that the regional override was created, list all consumer overrides for the limit:

gcurl "https://serviceusage.googleapis.com/v1beta1/${REGIONAL_LIMIT_RESOURCE_NAME}/consumerOverrides"

The newly created regional override should appear in the list:

{
  "overrides": [
    {
      "name": "projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion/consumerOverrides/Cg1RdW90YU92ZXJyaWRlGhwKBnJlZ2lvbhISc291dGhhbWVyaWNhLWVhc3Qx",
      "overrideValue": "65",
      "dimensions": {
        "region": "southamerica-east1"
      }
    }
  ]
}

Updating a consumer quota override

The owner of a project may also change the value of an existing consumer override on the project.

For example, suppose a previous create call returned an override with a name field like this:

name: "projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways/limits/%2Fproject/consumerOverrides/Cg1RdW90YU92ZXJyaWRl"

Then use that name to identify the override to be updated, like this:

OVERRIDE_RESOURCE_NAME="projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways/limits/%2Fproject/consumerOverrides/Cg1RdW90YU92ZXJyaWRl"
gcurl "https://serviceusage.googleapis.com/v1beta1/${OVERRIDE_RESOURCE_NAME}" -X PATCH -d '{"overrideValue": "13"}'

When the call succeeds, it returns an operation identifier, which represents ongoing work on the server, as the quota change propagates to backend systems:

{
  "name": "operations/quf.92accba3-6530-4fc1-9a95-c1280d48a6b7"
}

To check the progress of the operation, just use its name:

OPERATION_NAME="operations/quf.92accba3-6530-4fc1-9a95-c1280d48a6b7"
gcurl "https://serviceusage.googleapis.com/v1/${OPERATION_NAME}"

If the operation succeeds, then the response message includes done: true and contains the updated override resource. If the operation fails, then the response message includes done: true but contains error details instead of the updated resource.

To verify that the override was updated, list all consumer overrides for the limit:

LIMIT_RESOURCE_NAME="projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways/limits/%2Fproject"
gcurl "https://serviceusage.googleapis.com/v1beta1/${LIMIT_RESOURCE_NAME}/consumerOverrides"

The override should now appear in the list with its updated value:

{
  "overrides": [
    {
      "name": "projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways/limits/%2Fproject/consumerOverrides/Cg1RdW90YU92ZXJyaWRl",
      "overrideValue": "13"
    }
  ]
}

Deleting a consumer quota override

The owner of a project may also remove a consumer override from the project.

For example, suppose a previous create call returned an override with a name field like this:

name: "projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fdefault_requests/limits/%2Fmin%2Fproject/consumerOverrides/Cg1RdW90YU92ZXJyaWRl"

To delete the override, issue the following sequence:

OVERRIDE_RESOURCE_NAME="projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fdefault_requests/limits/%2Fmin%2Fproject/consumerOverrides/Cg1RdW90YU92ZXJyaWRl"
gcurl "https://serviceusage.googleapis.com/v1beta1/${OVERRIDE_RESOURCE_NAME}" -X DELETE

To verify that the override was deleted, list all consumer overrides for the limit:

LIMIT_RESOURCE_NAME="projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways/limits/%2Fproject"
gcurl "https://serviceusage.googleapis.com/v1beta1/${LIMIT_RESOURCE_NAME}/consumerOverrides"

The deleted override should no longer appear in the list.

Forcing large quota changes

If any quota override change would cause the enforced quota to decrease by more than 10%, the call is rejected, as a safety measure to avoid accidentally decreasing quota too quickly. To disregard this restriction, use the force flag. For example, here is a create call that takes the force flag:

LIMIT_RESOURCE_NAME="projects/${PROJECT_NUMBER}/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fexternal_vpn_gateways/limits/%2Fproject"
gcurl "https://serviceusage.googleapis.com/v1beta1/${LIMIT_RESOURCE_NAME}/consumerOverrides?force=true" -d '{"overrideValue": "0"}'