This page 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:
Quota increase adjustments must be made at the project-level and are subject to Google Cloud approval.
You can request quota decrease adjustments for project-, folder-, and organization-level quotas.
The Cloud Quotas API only supports project-level operations. Folder-level and organization-level operations are not supported.
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
QuotaInfo
resource 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/quotaInfos
ReplacePROJECT_NUMBER
with the project number for your project. - To find the CPUs per project and the applicable locations, look through the
QuotaInfo
response for theCPUS-per-project-region
quota ID. ThequotaValue
is 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-central1
has 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
quotaValue
in earlier steps to determine the usage.
In the following example response the usage value in Cloud Monitoring is 19 in theus-central1
region. ThequotaValue
for 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
ListQuotaPreferences
first to check if there are any pending requests. Thereconciling=true
flag 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
ReplacePROJECT_NUMBER
with the project number for your project. - Call
UpdateQuotaPreference
to increase the quota value for regionus-central1
. In the following example, a new preferred value of 100 has been specified.
The fieldallow_missing
is set totrue
. This tells the system to create aQuotaPreference
resource 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" } }
- Call
GetQuotaPreference
to check the status of the quota preference change:GET projects/PROJECT_NUMBER/locations/global/quotaPreferences/compute_googleapis_com-cpus-us-central1
ReplacePROJECT_NUMBER
with the project number for your project. While Google Cloud evaluates the requested quota value, the reconciling status is set totrue
."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, thereconciling
field is set tofalse
. ThegrantedValue
is 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
ListQuotaInfos
call:GET projects/PROJECT_NUMBER/locations/global/services/compute.googleapis.com/quotaInfos
ReplacePROJECT_NUMBER
with the project number for your project. - Look through the response fields to find a
QuotaInfo
entry 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 isV2-TPUS-per-project-region
, and the currentquotaValue
is 20. - Reduce TPU quota in each region to 10 with a
CreateQuotaPreferenceRequest
. Set thepreferredValue
to 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", "contactEmail": EMAIL }
- Confirm the new quota value with a
GetQuotaInfo
call 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-region
ReplacePROJECT_NUMBER
with the project number for your project. The following is an example response, thevalue
is 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
ListQuotaPreferences
on the source project with no filter:GET projects/PROJECT_NUMBER1/locations/global/quotaPreferences
PROJECT_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
UpdateQuotaPreference
and 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()) .setQuotaConfig( QuotaConfig.newBuilder().setPreferredValue(srcPreference.getQuotaConfig().getPreferredValue())) .putAllDimensions(srcPreference.getDimensionsMap()); UpdateQuotaPreferenceRequest updateRequest = UpdateQuotaPreferenceRequest.newBuilder() .setQuotaPreference(targetPreference) .setAllowMissing(true) .build(); cloudQuotas.updateQuotaPreference(updateRequest); }
- Call
ListQuotaPreferences
to verify the status of the quota preferences for the destination project:GET projects/PROJECT_NUMBER2/locations/global/quotaPreferences
ReplacePROJECT_NUMBER2
with 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) .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
: The reason for this request.EMAIL
: An email address that can be used as a contact, in case Google Cloud needs more information to make a decision 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-region
Replace 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"}, "contactEmail": "EMAIL" }
Replace the following:
PROJECT_NUMBER
: The unique identifier for your project.EMAIL
: An email address that can be used as a contact, in case Google Cloud needs more information to make a decision 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 that. 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) .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