Understand how Azure Resource Manager throttles requests
This article describes how Azure Resource Manager throttles requests. It shows you how to track the number of requests that remain before reaching the limit, and how to respond when you reach the limit.
Throttling happens at two levels. Azure Resource Manager throttles requests for the subscription and tenant. If the request is under the throttling limits for the subscription and tenant, Resource Manager routes the request to the resource provider. The resource provider applies throttling limits that are tailored to its operations.
Subscription and tenant limits
Every subscription-level and tenant-level operation is subject to throttling limits. Subscription requests are ones that involve passing your subscription ID, such as retrieving the resource groups in your subscription. For example, sending a request to https://management.chinacloudapi.cn/subscriptions/{subscriptionId}/resourceGroups?api-version=2022-01-01
is a subscription-level operation. Tenant requests don't include your subscription ID, such as retrieving valid Azure locations. For example, sending a request to https://management.chinacloudapi.cn/tenants?api-version=2022-01-01
is a tenant-level operation.
The default throttling limits per hour are shown in the following table.
Scope | Operations | Limit |
---|---|---|
Subscription | reads | 12000 |
Subscription | deletes | 15000 |
Subscription | writes | 1200 |
Tenant | reads | 12000 |
Tenant | writes | 1200 |
These limits are scoped to the security principal (user or application) making the requests and the subscription ID or tenant ID. If your requests come from more than one security principal, your limit across the subscription or tenant is greater than 12,000 and 1,200 per hour.
These limits apply to each Azure Resource Manager instance. There are multiple instances in every Azure region, and Azure Resource Manager is deployed to all Azure regions. So, in practice, the limits are higher than these limits. The requests from a user are usually handled by different instances of Azure Resource Manager.
The remaining requests are returned in the response header values.
Resource provider limits
Resource providers apply their own throttling limits. Within each subscription, the resource provider throttles per region of the resource in the request. Because Resource Manager throttles by instance of Resource Manager, and there are several instances of Resource Manager in each region, the resource provider might receive more requests than the default limits in the previous section.
This section discusses the throttling limits of some widely used resource providers.
Storage throttling
The following limits apply only when you perform management operations by using Azure Resource Manager with Azure Storage. The limits apply per region of the resource in the request.
Resource | Limit |
---|---|
Storage account management operations (read) | 800 per 5 minutes |
Storage account management operations (write) | 10 per second / 1200 per hour |
Storage account management operations (list) | 100 per 5 minutes |
Network throttling
The Microsoft.Network resource provider applies the following throttle limits:
Operation | Limit |
---|---|
write / delete (PUT) | 1000 per 5 minutes |
read (GET) | 10000 per 5 minutes |
In addition to those general limits, the following limits apply to DNS operations:
DNS Zone Operation | Limit (per zone) |
---|---|
Create or Update | 40 per minute |
Delete | 40 per minute |
Get | 1000 per minute |
List | 60 per minute |
List By Resource Group | 60 per minute |
Update | 40 per minute |
DNS Record Set Operation | Limit (per zone) |
---|---|
Create or Update | 200 per minute |
Delete | 200 per minute |
Get | 2000 per minute |
List By DNS Zone | 60 per minute |
List By Type | 60 per minute |
Update | 200 per minute |
Compute throttling
For information about throttling limits for compute operations, see Troubleshooting API throttling errors - Compute.
For checking virtual machine instances within a Virtual Machine Scale Set, use the Virtual Machine Scale Sets operations. For example, use the Virtual Machine Scale Set VMs - List with parameters to check the power state of virtual machine instances. This API reduces the number of requests.
Azure Resource Graph throttling
Azure Resource Graph limits the number of requests to its operations. The steps in this article to determine the remaining requests and how to respond when the limit is reached also apply to Resource Graph. However, Resource Graph sets its own limit and reset rate. For more information, see Resource Graph throttling headers.
Other resource providers
For information about throttling in other resource providers, see:
Error code
When you reach the limit, you receive the HTTP status code 429 Too many requests. The response includes a Retry-After value, which specifies the number of seconds your application should wait (or sleep) before sending the next request. If you send a request before the retry value elapses, your request isn't processed and a new retry value is returned.
If you're using an Azure SDK, the SDK may have an auto retry configuration.
Some resource providers return 429 to report a temporary problem. The problem could be an overload condition that isn't directly caused by your request. Or, it could represent a temporary error about the state of the target resource or dependent resource. For example, the network resource provider returns 429 with the RetryableErrorDueToAnotherOperation error code when the target resource is locked by another operation. To determine if the error comes from throttling or a temporary condition, view the error details in the response.
Remaining requests
You can determine the number of remaining requests by examining response headers. Read requests return a value in the header for the number of remaining read requests. Write requests include a value for the number of remaining write requests. The following table describes the response headers you can examine for those values:
Response header | Description |
---|---|
x-ms-ratelimit-remaining-subscription-deletes | Subscription scoped deletes remaining. This value is returned on delete operations. |
x-ms-ratelimit-remaining-subscription-reads | Subscription scoped reads remaining. This value is returned on read operations. |
x-ms-ratelimit-remaining-subscription-writes | Subscription scoped writes remaining. This value is returned on write operations. |
x-ms-ratelimit-remaining-tenant-reads | Tenant scoped reads remaining |
x-ms-ratelimit-remaining-tenant-writes | Tenant scoped writes remaining |
x-ms-ratelimit-remaining-subscription-resource-requests | Subscription scoped resource type requests remaining. This header value is only returned if a service overrides the default limit. Resource Manager adds this value instead of the subscription reads or writes. |
x-ms-ratelimit-remaining-subscription-resource-entities-read | Subscription scoped resource type collection requests remaining. This header value is only returned if a service overrides the default limit. This value provides the number of remaining collection requests (list resources). |
x-ms-ratelimit-remaining-tenant-resource-requests | Tenant scoped resource type requests remaining. This header is only added for requests at tenant level, and only if a service overrides the default limit. Resource Manager adds this value instead of the tenant reads or writes. |
x-ms-ratelimit-remaining-tenant-resource-entities-read | Tenant scoped resource type collection requests remaining. This header is only added for requests at tenant level, and only if a service overrides the default limit. |
The resource provider can also return response headers with information about remaining requests. For information about response headers returned by the Compute resource provider, see Call rate informational response headers.
Retrieving the header values
Retrieving these header values in your code or script is no different than retrieving any header value.
For example, in C#, you retrieve the header value from an HttpWebResponse object named response with the following code:
response.Headers.GetValues("x-ms-ratelimit-remaining-subscription-reads").GetValue(0)
In PowerShell, you retrieve the header value from an Invoke-WebRequest operation.
$r = Invoke-WebRequest -Uri https://management.chinacloudapi.cn/subscriptions/{guid}/resourcegroups?api-version=2016-09-01 -Method GET -Headers $authHeaders
$r.Headers["x-ms-ratelimit-remaining-subscription-reads"]
For a complete PowerShell example, see Check Resource Manager Limits for a Subscription.
If you want to see the remaining requests for debugging, you can provide the -Debug parameter on your PowerShell cmdlet.
Get-AzResourceGroup -Debug
Which returns many values, including the following response value:
DEBUG: ============================ HTTP RESPONSE ============================
Status Code:
OK
Headers:
Pragma : no-cache
x-ms-ratelimit-remaining-subscription-reads: 11999
To get write limits, use a write operation:
New-AzResourceGroup -Name myresourcegroup -Location chinanorth -Debug
Which returns many values, including the following values:
DEBUG: ============================ HTTP RESPONSE ============================
Status Code:
Created
Headers:
Pragma : no-cache
x-ms-ratelimit-remaining-subscription-writes: 1199
In Azure CLI, you retrieve the header value by using the more verbose option.
az group list --verbose --debug
Which returns many values, including the following values:
msrest.http_logger : Response status: 200
msrest.http_logger : Response headers:
msrest.http_logger : 'Cache-Control': 'no-cache'
msrest.http_logger : 'Pragma': 'no-cache'
msrest.http_logger : 'Content-Type': 'application/json; charset=utf-8'
msrest.http_logger : 'Content-Encoding': 'gzip'
msrest.http_logger : 'Expires': '-1'
msrest.http_logger : 'Vary': 'Accept-Encoding'
msrest.http_logger : 'x-ms-ratelimit-remaining-subscription-reads': '11998'
To get write limits, use a write operation:
az group create -n myresourcegroup --location chinanorth --verbose --debug
Which returns many values, including the following values:
msrest.http_logger : Response status: 201
msrest.http_logger : Response headers:
msrest.http_logger : 'Cache-Control': 'no-cache'
msrest.http_logger : 'Pragma': 'no-cache'
msrest.http_logger : 'Content-Length': '163'
msrest.http_logger : 'Content-Type': 'application/json; charset=utf-8'
msrest.http_logger : 'Expires': '-1'
msrest.http_logger : 'x-ms-ratelimit-remaining-subscription-writes': '1199'
Next steps
- For more information about limits and quotas, see Azure subscription and service limits, quotas, and constraints.
- To learn about handling asynchronous REST requests, see Track asynchronous Azure operations.