This page outlines various limits and limitations in Google Ads scripts that you
should be aware of. These limits can change at any time without warning, so
ensure that your scripts are flexible and contain error handling.

## Execution time limits

### Google Ads scripts

Google Ads scripts for advertiser accounts can execute for a **maximum of 30
minutes**, after which they will be cancelled. All of the changes made
before the script was cancelled will be applied.

### Ads Manager scripts

Ads Manager scripts can normally execute for a **maximum of 30 minutes** , after
which they will be cancelled. However, if an Ads Manager script uses the
[`executeInParallel`](https://developers.google.com/google-ads/scripts/docs/reference/adsmanagerapp/adsmanagerapp_managedaccountselector#executeInParallel_functionName-optionalCallbackFunctionName)
method to process accounts in parallel and specifies a callback method, then it
can execute up to a **maximum of 60 minutes** before being cancelled. This is
illustrated in the following figure, where `processAccount` is the parallel
function, and `allFinished` is the callback method when calling
[`executeInParallel`](https://developers.google.com/google-ads/scripts/docs/reference/adsmanagerapp/adsmanagerapp_managedaccountselector#executeInParallel_functionName-optionalCallbackFunctionName).

![](https://developers.google.com/static/google-ads/scripts/images/executeinparallel_time_limits.png)

All of the changes made before the script was cancelled will be applied.

## Entity limits

> [!NOTE]
> **Note:** [Reports](https://developers.google.com/google-ads/scripts/docs/concepts/reports) are not subject to any entity limits.

### Scripts of Google Ads accounts

- A single **iterator** will default to at most 50,000 results returned. You
  can modify this by calling `withLimit()` on the selector.

- A single **selector** can handle at most 10,000 IDs in `selector.withIds()`.
  If 10,000 or more IDs are specified, `selector.get()` will throw a runtime
  error. Similarly, specifying an `Id IN [LIST]` condition with a list of more
  than 10,000 IDs will result in a runtime error.

- Logging output will be truncated at 100Kb. A warning will be logged if that
  happens.

### Scripts of manager accounts

- Each account processed by an Ads Manager script gets its own quota as
  [listed in the previous section](https://developers.google.com/google-ads/scripts/docs/limits#scripts_of_google_ads_accounts).

- When using the `executeInParallel` method, a script can process up to **50**
  accounts.

- The `processAccount` method from `executeInParallel` can return up to
  **10MB** of data.

## Bulk upload limits

- The upload file is limited to 50MB and one million rows, and will be rejected
  upon submission if it exceeds these limits.

- An upload job times out after two hours and the job will stop processing any
  remaining data from the uploaded file.

## Quotas for Google services

The underlying Google Apps Script services impose daily quotas and hard limits
on some features. See a list of these
[quotas and accompanying exception messages](https://developers.google.com/apps-script/guides/services/quotas).

> [!IMPORTANT]
> **Key Point:** To get around the "Exceeded maximum execution time" error, you can reschedule your script under multiple user accounts to extend the script's quota.

## Authorized scripts

OAuth2 is used to authorize scripts. Each account has a limit of **250**
authorized scripts. Beyond that limit, one of the previously authorized
scripts will be deauthorized. This is only temporary, and the script can be
reauthorized the next time it is opened.

If you are frequently running into this limit, you should consider using
multiple user accounts to authorize different sets of scripts.

## Video and shopping campaigns

The standard campaign selector (`AdsApp.campaigns().get()`) will filter
out [video](https://support.google.com/google-ads/answer/2375497) and
[shopping](https://support.google.com/google-ads/answer/3455481) campaigns
from the results. Use the dedicated campaign selectors instead:

- [`videoCampaignSelector.get()`](https://developers.google.com/google-ads/scripts/docs/reference/adsapp/adsapp_videocampaignselector)
- [`shoppingCampaignSelector.get()`](https://developers.google.com/google-ads/scripts/docs/reference/adsapp/adsapp_shoppingcampaignselector)