This document describes how to implement common use cases using the Cloud Quotas API. This API lets you programmatically adjust quotas and automate quota adjustments in your Google Cloud projects, folders, or organization.
To learn more, see the Cloud Quotas API overview and reference.
Limitations
Cloud Quotas has the following limitations:
In most cases, quota increase adjustments must be made at the project-level. A limited number of products support organization-level quota increase adjustments. To see if a Google Cloud product supports organization-level quota increase adjustments, refer to the documentation for that product.
You can request quota decrease adjustments for project-, organization-, and folder-level quotas.
Track usage and request an increase when usage is over 80%
This example tracks quota usage with Cloud Monitoring and then requests an increase when the usage is over 80%.
Call the
QuotaInforesource for your service to determine the currentquotaValue. The service in this example iscompute.googleapis.com:GET projects/PROJECT_NUMBER/locations/global/services/compute.googleapis.com/quotaInfosReplace
PROJECT_NUMBERwith the project number for your project.To find the CPUs per project and the applicable locations, look through the
QuotaInforesponse for theCPUS-per-project-regionquota ID. ThequotaValueis 20."quotaInfos": [ ... { "name": "projects/PROJECT_NUMBER/locations/global/services/compute.googleapis.com/quotaInfos/CPUS-per-project-region", "quotaId": "CPUS-per-project-region", "metric": "compute.googleapis.com/cpus", "containerType": "PROJECT", "dimensions": [ "region" ], "dimensionsInfo": [ { "dimensions": [], "details": { "quotaValue": 20, "resetValue": 20 }, "applicableLocations": [ "us-central1", "us-central2", "us-west1", "us-east1" ] } ] }, ... ]
Call the Cloud Monitoring API to find the quota usage. In the following example, the region
us-central1has been specified. Supported quota metrics are listed underserviceruntime.{ "name": "projects/PROJECT_NUMBER" "filter": "metric.type=\"serviceruntime.googleapis.com/quota/allocation/usage\" AND metric.labels.quota_metric=\"compute.googleapis.com/cpus\" AND resource.type=\"consumer_quota\" AND resource.label.location=\"us-central1\" ", "interval": { "startTime": "2023-11-10T18:18:18.0000Z", "endTime": "2023-11-17T18:18:18.0000Z" }, "aggregation": { "alignmentPeriod": "604800s", // 7 days "perSeriesAligner": "ALIGN_MAX", "crossSeriesReducer": "REDUCE_MAX" } }
To determine your usage, handle the response from the Cloud Monitoring API. Compare the value from Cloud Monitoring to the
quotaValuein earlier steps to determine the usage.In the following example response the usage value in Cloud Monitoring is 19 in the
us-central1region. ThequotaValuefor all regions is 20. The usage is greater than 80% of the quota, and a quota preference update can be initiated.time_series { metric { labels { key: "quota_metric" value: "compute.googleapis.com/cpus" } type: "serviceruntime.googleapis.com/quota/allocation/usage" } resource { type: "consumer_quota" labels { key: "project_id" value: "PROJECT_ID" } labels { key: "location" value: "us-central1" } } metric_kind: GAUGE value_type: INT64 points { interval { start_time { seconds: "2023-11-10T18:18:18.0000Z" } end_time { seconds: "2023-11-17T18:18:18.0000Z" } } value { int64_value: 19 } } }
To avoid duplicated quota preferences, call
ListQuotaPreferencesfirst to check if there are any pending requests. Thereconciling=trueflag calls pending requests.GET projects/PROJECT_NUMBER/locations/global/quotaPreferences?filter=service=%22compute.googleapis.com%22%20AND%20quotaId=%22CPUS-per-project-region%22%20AND%20reconciling=true
Replace
PROJECT_NUMBERwith the project number for your project.Call
UpdateQuotaPreferenceto increase the quota value for regionus-central1. In the following example, a new preferred value of 100 has been specified.The field
allow_missingis set totrue. This tells the system to create aQuotaPreferenceresource where none exists with the provided name.PATCH projects/PROJECT_NUMBER/locations/global/quotaPreferences/compute_googleapis_com-cpus-us-central1?allowMissing=true { "service": "compute.googleapis.com", "quotaId": "CPUS-per-project-region", "quotaConfig": { "preferredValue": 100 }, "dimensions": { "region": "us-central1" }, "justification": "JUSTIFICATION", "contactEmail": "EMAIL" }
Replace the following:
PROJECT_NUMBER: The unique identifier for your project.JUSTIFICATION: An optional string that explains your request.EMAIL: An email address that can be used as a contact, in case Google Cloud needs more information before additional quota can be granted.
Call
GetQuotaPreferenceto check the status of the quota preference change:GET projects/PROJECT_NUMBER/locations/global/quotaPreferences/compute_googleapis_com-cpus-us-central1Replace
PROJECT_NUMBERwith the project number for your project.While Google Cloud evaluates the requested quota value, the reconciling status of your quota is set to
true.Sometimes Google Cloud approves part of your increase request instead of approving the full increase. If the request is partially approved, the quota preference includes a
stateDetailfield. ThestateDetailfield describes the partially approved state. ThegrantedValuefield shows the adjustment that was made to partially fulfill your request.To see if the granted value is the final value approved, look at the
reconcilingfield. If your request is still undergoing evaluation, thereconcilingfield is set totrue. If thereconcilingfield is set tofalseor is omitted, the granted value is the final value approved.In the following example, the requested quota value is 100 and the
reconcilingfield indicates that the request is undergoing review."name": "projects/PROJECT_NUMBER/locations/global/quotaPreferences/compute_googleapis_com-cpus-us-central1", "service": "compute.googleapis.com", "quotaId": "CPUS-per-project-region", "quotaConfig": { "preferredValue": 100, "grantedValue": 50, "traceId": "123acd-345df23", "requestOrigin": "ORIGIN_UNSPECIFIED" }, "dimensions": { "region": "us-central1" }, "reconciling": true, "createTime": "2023-01-15T01:30:15.01Z", "updateTime": "2023-01-16T02:35:16.01Z"
After the quota preference has been processed, the
reconcilingfield is set tofalse. ThegrantedValueis the same as thepreferredValue. The preferred quota is fully granted.When Google Cloud denies or partially approves a customer request, the granted quota value can still be less than the preferred value.
Decrease a quota
The following example decreases the number of TPUs to 10 in each region.
Get the quota ID and the current quota value with a
ListQuotaInfoscall:GET projects/PROJECT_NUMBER/locations/global/services/compute.googleapis.com/quotaInfosReplace
PROJECT_NUMBERwith the project number for your project.Look through the response fields to find a
QuotaInfoentry forV2-TPUS-per-project-region."quotaInfos": [ ... { "name": "projects/PROJECT_NUMBER/locations/global/services/compute.googleapis.com/quotaInfos/V2-TPUS-per-project-region", "quotaId": "V2-TPUS-per-project-region", "metric": "compute.googleapis.com/Tpus", "containerType": "PROJECT", "dimensions": [ "region" ], "dimensionsInfo": [ { "dimensions": [], "details": { "quotaValue": 20, "resetValue": 20 }, "applicableLocations": [ "us-central1", "us-central2", "us-west1", "us-east1" ] } ] }, ... ]
In this response the quota ID is
V2-TPUS-per-project-region, and the currentquotaValueis 20.Reduce TPU quota in each region to 10 with a
CreateQuotaPreferenceRequest. Set thepreferredValueto 10.POST projects/PROJECT_NUMBER/locations/global/quotaPreferences?quotaPreferenceId=compute_googleapis_com-Tpu-all-regions { "quotaConfig": { "preferredValue": 10 }, "dimensions": [], "service": "compute.googleapis.com", "quotaId": "V2-TPUS-per-project-region", "justification": "JUSTIFICATION", "contactEmail": "EMAIL" }
Replace the following:
PROJECT_NUMBER: The unique identifier for your project.JUSTIFICATION: An optional string that explains your request.EMAIL: An email address that can be used as a contact, in case Google Cloud needs more information before additional quota can be granted.
Confirm the new quota value with a
GetQuotaInfocall that defines the quota ID asV2-TPUS-per-project-region.GET projects/PROJECT_NUMBER/locations/global/services/compute.googleapis.com/quotaInfos/V2-TPUS-per-project-regionReplace
PROJECT_NUMBERwith the project number for your project.The following is an example response, the
valueis 10 and it is applicable in all regions."name": "projects/PROJECT_NUMBER/locations/global/services/compute.googleapis.com/quotaInfos/V2-TPUS-per-project-region", "quotaId": "V2-TPUS-per-project-region", "metric": "compute.googleapis.com/v2_tpus", "containerType": "PROJECT", "dimensions": [ "region" ], "dimensionsInfo": [ { "dimensions": [], "details": { "value": 10, }, "applicableLocations": [ "us-central1", "us-central2", "us-west1", "us-east1" ] } ]
Copy quota preferences to another project
The following example copies all quota preferences from one project to another. It's written in Java, but you can use any programming language.
Call
ListQuotaPreferenceson the source project with no filter:GET projects/PROJECT_NUMBER1/locations/global/quotaPreferencesPROJECT_NUMBER1 is the project number for the source project. The response contains all quota preferences for the source project.
For each quota preference in the response, call
UpdateQuotaPreferenceand define the following fields:name- The updated name field is taken from the response, and the source project number (PROJECT_NUMBER1) is replaced with the destination project number (PROJECT_NUMBER2).service,quotaId,preferredValue,dimensions- These fields can be taken directly from the response as is.
for (QuotaPreference srcPreference : listResponse.getQuotaPreferences()) { QuotaPreference.Builder targetPreference = QuotaPreference.newBuilder() .setName(srcPreference.getName().replace("PROJECT_NUMBER1", "PROJECT_NUMBER2")) .setService(srcPreference.getService()) .setQuotaId(srcPreference.getQuotaId()) .setJustification(srcPreference.getJustification()) .setContactEmail(srcPreference.getContactEmail()) .setQuotaConfig( QuotaConfig.newBuilder().setPreferredValue(srcPreference.getQuotaConfig().getPreferredValue())) .putAllDimensions(srcPreference.getDimensionsMap()); UpdateQuotaPreferenceRequest updateRequest = UpdateQuotaPreferenceRequest.newBuilder() .setQuotaPreference(targetPreference) .setAllowMissing(true) .build(); cloudQuotas.updateQuotaPreference(updateRequest); }
Call
ListQuotaPreferencesto verify the status of the quota preferences for the destination project:GET projects/PROJECT_NUMBER2/locations/global/quotaPreferencesReplace
PROJECT_NUMBER2with the project number for your destination project.
List pending quota requests
To list all pending quota preference requests for a project, call
ListQuotaPreferences with the filter reconciling=true.
GET projects/PROJECT_NUMBER/locations/global/quotaPreferences?reconciling=true
Replace PROJECT_NUMBER with the project number for your
project.
The response for this request returns the latest pending quota preference. Because Cloud Quotas API is a declarative API, the latest quota preference is what the system tries to fulfill.
An example response looks similar to the following:
"quotaPreferences": [ { "name": "projects/PROJECT_NUMBER/locations/global/quotaPreferences/compute_googleapis_com-cpus-us-central1", "service": "compute.googleapis.com", "quotaId": "CPUS-per-project-region", "quotaConfig": { "preferredValue": 100, "grantedValue": 30, "traceId": "123acd-345df23", "requestOrigin": "ORIGIN_UNSPECIFIED" }, "dimensions": { "region": "us-central1" }, "reconciling": true, "createTime": "2023-01-15T01:30:15.01Z", "updateTime": "2023-01-16T02:35:16.01Z" }, { "name": "projects/PROJECT_NUMBER/locations/global/quotaPreferences/compute_googleapis_com-cpus-cross-regions", "service": "compute.googleapis.com", "quotaId": "CPUS-per-project-region", "quotaConfig": { "preferredValue": 10, "grantedValue": 5, "traceId": "456asd-678df43", "requestOrigin": "ORIGIN_UNSPECIFIED" }, "reconciling": true, "createTime": "2023-01-15T01:35:15.01Z", "updateTime": "2023-01-15T01:35:15.01Z" } ]
Request group quota increases
To request increases for a group of quotas in a new project, store the preferred quotas for the new project in a CSV file with the following values: service name, quota ID, preferred quota value, dimensions.
For each row in the CSV file, read the contents into the fields serviceName,
quotaId, preferredValue, and dimensionMap.
CreateQuotaPreferenceRequest request = CreateQuotaPreferenceRequest.newBuilder() .setParent("projects/PROJECT_NUMBER/locations/global") .setQuotaPreferenceId(buildYourOwnQuotaPreferenceId(serviceName, quotaId, dimensionMap)) .setQuotaPreference( QuotaPreference.newBuilder() .setService(serviceName) .setQuotaId(quotaId) .setJustification(justification) .setContactEmail(contactEmail) .setQuotaConfig(QuotaConfig.newBuilder().setPreferredValue(preferredValue)) .putAllDimensions(dimensionMap)) .build(); cloudQuotas.createQuotaPreference(request);
Replace PROJECT_NUMBER with the project number for your
project.
Because the target project is new, it is safe to call the
CreateQuotaPreference method as you read and assign the fields. Alternatively,
you can call the UpdateQuotaPreference method with allow_missing set to true.
The method buildYourOwnQuotaPreferenceId builds a quota preference ID
from service name, quota ID, and a map of dimensions according to your naming
scheme. Alternatively, you can choose not to set quota preference ID. A quota
preference ID is generated for you.
Request adjustments on quotas that have no usage
For quotas that don't already have quota usage and that have service-specific
dimensions such as vm_family, it is possible that those quotas might not
be visible in the Google Cloud console. You may need to use the
Cloud Quotas API instead.
For example, you might clone a project and know ahead of time that you need to
increase the value for compute.googleapis.com/gpus_per_gpu_family.
This value only appears in the Google Cloud console for GPU families that you have
already used. To use the Cloud Quotas API to request an increase to
NVIDIA_H100 GPUs in us-central1, you could send a request like the following:
POST projects/PROJECT_NUMBER/locations/global/quotaPreferences?quotaPreferenceId=compute_googleapis_com-gpus-us-central1-NVIDIA_H100 {
"service": "compute.googleapis.com",
"quotaId": "GPUS-PER-GPU-FAMILY-per-project-region",
"quotaConfig": { "preferredValue": 100 },
"dimensions": { "region": "us-central1", "gpu_family": "NVIDIA_H100" },
"justification": "JUSTIFICATION",
"contactEmail": "EMAIL"
}
Replace the following:
PROJECT_NUMBER: The unique identifier for your project.JUSTIFICATION: An optional string that explains your request.EMAIL: An email address that can be used as a contact, in case Google Cloud needs more information before additional quota can be granted.
For more information, see also the descriptions of Dimension precedence and Combining dimensions.
Get quota info for a service specific dimension
GPU family is a service specific dimension. The following example request uses the
GPUS-PER-GPU-FAMILY-per-project-region quota ID to get the QuotaInfo resource.
GET projects/PROJECT_NUMBER/locations/global/services/compute.googleapis.com/quotaInfos/GPUS-PER-GPU-FAMILY-per-project-regionReplace PROJECT_NUMBER with the project number for your
project.
This is an example response. For each unique gpu_family key, the quotaValue
and applicableLocations is different:
"name": "projects/PROJECT_NUMBER/locations/global/services/compute.googleapis.com/quotaInfos/GpusPerProjectPerRegion", "quotatName": "CPUS-per-project-region", "metric": "compute.googleapis.com/gpus_per_gpu_family", "isPrecise": true, "quotaDisplayName": "GPUs per GPU family", "metricDisplayName": "GPUs", "dimensions": [ "region", "gpu_family" ], "dimensionsInfo": [ { "dimensions": { "region": "us-central1", "gpu_family": "NVIDIA_H200" }, "details": { "quotaValue": 30, "resetValue": 30, }, "applicableLocations": [ "us-central1" ] }, { "dimensions": { "region": "us-central1" } "details": { "quotaValue": 100, "resetValue": 100, }, "applicableLocations": [ "us-central1" ] }, { "dimensions": { "gpu_familly": "NVIDIA_H100" } "details": { "quotaValue": 10, }, "applicableLocations": [ "us-central2", "us-west1", "us-east1" ] } { "dimensions": [], "details": { "quotaValue": 50, "resetValue": 50, }, "applicableLocations": [ "us-central1", "us-central2", "us-west1", "us-east1" ] } ]
Create a quota preference for a service specific dimension
The following example demonstrates how to create a quota for a given region and
GPU family with a preferred value of 100. The target location is specified in the
map of dimensions with the key region, and the target GPU family with the key
gpu_family.
The following CreateQuotaPreference example specifies a GPU family of
NVIDIA_H100 and a region of us-central1.
POST projects/PROJECT_NUMBER/locations/global/quotaPreferences?quotaPreferenceId=compute_googleapis_com-gpus-us-central1-NVIDIA_H100 { "service": "compute.googleapis.com", "quotaId": "GPUS-PER-GPU-FAMILY-per-project-region", "quotaConfig": { "preferredValue": 100 }, "dimensions": {"region": "us-central1", "gpu_family": "NVIDIA_H100"}, "justification": "JUSTIFICATION", "contactEmail": ""EMAIL" }
Replace the following:
PROJECT_NUMBER: The unique identifier for your project.JUSTIFICATION: An optional string that explains your request.EMAIL: An email address that can be used as a contact, in case Google Cloud needs more information before additional quota can be granted.
Update a quota preference for a service specific dimension
The following sample code gets the current value for the dimension
{"region" : "us-central1"; gpu_family:"NVIDIA_H100"},
and then sets the preferred value to double the value. It's written in Java, but you
can use any programming language.
// Get the current quota value for the target dimensions Map<String, String> targetDimensions = Maps.createHashMap("region", "us-central1", "gpu_family", "NVIDIA_H100"); long currentQuotaValue = 0; QuotaInfo quotaInfo = cloudQuotas.GetQuotaInfo( "projects/PROJECT_NUMBER/locations/global/services/" + serviceName + "quotaInfos/" + quotaId; for (dimensionsInfo : quotaInfo.getDimensionsInfoList()) { If (targetDimensions.entrySet().containsAll(dimensionsInfo.getDimensionsMap().entrySet()) { currentQuotaValue = dimensionsInfo.getDetails().getValue(); break; }) } // Set the preferred quota value to double the current value for the target dimensions QuotaPreference.Builder targetPreference = QuotaPreference.newBuilder() .setName(buildYourOwnQuotaPreferenceId(serviceName, quotaId, targetDimensions)) .setService(serviceName) .setQuotaId(quotaId) .setJustification(justification) .setContactEmail(contactEmail) .setQuotaConfig(QuotaConfig.newBuilder().setPreferredValue(currentQuotaValue * 2)) .putAllDimensions(targetDimensions)); UpdateQuotaPreferenceRequest updateRequest = UpdateQuotaPreferenceRequest.newBuilder() .setQuotaPreference(targetPreference) .setAllowMissing(true) .build(); cloudQuotas.updateQuotaPreference(updateRequest);
Replace PROJECT_NUMBER with the unique identifier for
your project.
What's next
About the Cloud Quotas API
Cloud Quotas API reference
Understand quotas