Rate limits

  • Google Ads API rate limits requests by queries per second (QPS) per client customer ID and developer token using a Token Bucket algorithm.

  • Rate limits prevent users from overwhelming API servers with high request volumes.

  • Requests exceeding rate limits receive a RESOURCE_TEMPORARILY_EXHAUSTED error.

  • Reducing the number of requests and throttling QPS from the client side can help mitigate rate limits.

  • Strategies to manage rate limits include limiting concurrent tasks, batching requests, implementing throttling and rate limiters, and using queueing.

The Google Ads API enforces rate limiting by queries per second (QPS) on both customer IDs and Google Cloud projects independently. In addition to requests per minute (which measure the frequency of API calls), the Google Ads API also enforces limits on operations per minute (which measure the total number of API operations across requests). The Google Ads API uses a token bucket algorithm to meter requests and determine an appropriate QPS limit, so the exact limit varies depending on the overall server load at any given time.

The purpose of imposing rate limits is to prevent one user from disrupting service for other users by (either intentionally or unintentionally) overwhelming the Google Ads API servers with a high volume of requests.

Requests that violate rate limits are rejected with the error: RESOURCE_TEMPORARILY_EXHAUSTED.

You can take control of your app and mitigate rate limits by both actively reducing the number of requests and throttling QPS from the client side.

There are a number of ways to reduce the chances of exceeding the rate limit. Becoming familiar with Enterprise Integration Patterns (EIP) concepts such as messaging, re-delivery, and throttling can help you build a more robust client app.

The following recommended practices are ordered by complexity, with simpler strategies at the top and more robust but sophisticated architectures after:

Exponential backoff

When your application receives a RESOURCE_TEMPORARILY_EXHAUSTED error, use an exponential backoff policy with randomized jitter before retrying the failed request. Exponential backoff progressively increases the wait time between retries (for example, waiting 2 seconds, then 4 seconds, then 8 seconds, plus a small random delay), allowing server load and quota buckets to recover while preventing synchronized retry spikes across client instances.

Limit concurrent tasks

One root cause of exceeding rate limits is that the client app is spawning an excessive number of parallel tasks. While we don't limit the number of parallel requests a client app can have, this can exceed the requests per second limit at the Google Cloud project level.

Setting a reasonable upper bound for the total number of concurrent tasks that are going to make requests (across all processes and machines), and adjusting upward to optimize your throughput without exceeding the rate limit is recommended.

Furthermore, you can consider throttling QPS from the client side (see Throttling and rate limiters).

Batching requests

Consider batching multiple operations into a single request. This is most applicable on Mutate calls for various services. For example, if you're updating status for multiple instances of AdGroupAd, you can call MutateAdGroupAds once, and pass in multiple operations instead of calling MutateAdGroupAds once for each AdGroupAd. Refer to our batch operations guidance for some additional examples.

While batching requests reduces the total number of API calls and mitigates the rate limits on requests per minute, it may trigger the operations per minute rate limit if you perform a large number of operations against a single account.

Throttling and rate limiters

In addition to limiting the total number of threads in your application, you can also implement rate limiters on the client side. This ensures all threads across your processes, clusters, or both are governed by a specific QPS limit from the client side.

See the Guava RateLimiter, or implement your own token bucket algorithm for a clustered environment. For example, you can manage tokens in a distributed, low-latency in-memory datastore such as Redis or Memcached, where each client acquires and consumes a token before processing a request. If the tokens are exhausted, the client waits until the next batch of tokens is replenished.

Queueing

A message queue is the solution for operation load distribution, while also controlling request and consumer rates. There are a number of message queue options available—some open source, some proprietary—and many of them can work with different languages.

When using message queues, you can have multiple producers pushing messages to the queue and multiple consumers processing those messages. Throttles can be implemented at the consumer side by limiting the number of concurrent consumers, or by implementing rate limiters or throttlers for either the producers or consumers.

For example, if a message consumer encounters a rate limit error, that consumer can return the request to the queue with a standardized retry delay (using exponential backoff) and update a shared rate-limiter feedback loop so that all consumers automatically reduce their processing rate while recovering from the error.