The new Google Ads scripts infrastructure is based on the Google Ads API. Because of the different architecture of that API, you may need to update your existing scripts. We have made every effort to ensure as much backwards compatibility as possible, so these changes should be minor.


Many AWQL reports will continue to function. Behind the scenes, when using the new infrastructure, scripts will convert your AWQL query to GAQL (the new query language for the Google Ads API), run it against the new backend, and then convert the results back to the format originally used by AWQL reports. Queries with GAQL will pass through as is.

Because of this overhead, we recommend that you go through your scripts and update AWQL queries to GAQL wherever possible. You can use the query migration tool which uses the same logic as scripts to determine the GAQL query for a given AWQL query, or you can use the interactive query builder to help construct queries.

Here are some limitations to the automatic AWQL-to-GAQL translation:

  • Not all AWQL queries cleanly translate to GAQL queries. In these cases, an error message with some details about what went wrong will be logged, to help you in manually fixing them.
  • Not all report types from AWQL are supported in GAQL.
  • GAQL has no support for "zero impression rows". Specifying that a report should include zero impressions will result in an error.
  • Some ambiguous fields cannot be used in filters. For example, "Headline" could reference any number of different ad fields.
  • Some fields may return results in a different format, for example, breaking up one result into many columns.

Organizing selectors

When fetching resources using scripts, it's fairly common to use withCondition and orderBy calls to restrict or order the results in the iterator. The fields in these calls now use the new Google Ads API names. For example, to filter by campaign name, previously you would have used:

.withCondition('CampaignName = "SOME_CAMPAIGN_NAME"')

Now, you should use the new field names for these conditions wherever possible:

.withCondition('campaign.name = "SOME_CAMPAIGN_NAME"')

That said, we have made an effort to include a mapping of old names to new names, so if your script still uses CampaignName, it would automatically be replaced with campaign.name at runtime to ensure the script still works. If you run into any issues with the old style names, update your scripts to use the new style names as a first troubleshooting step.


Many limits are the same as they were on the old infrastructure, and the changes made here will generally help boost performance.

  • Time limits are the same. A script may execute for 30 minutes.
  • A single iterator returns 50,000 entities by default, but this can be overridden. Previously, this 50,000 limit was not customizeable.
  • A single selector can handle at most 10,000 IDs (unchanged).
  • The new infrastructure has no limit on the number of entities that can be processed in a single script. Previously the limit was 250,000.
  • The new infrastructure has no limit on the number of keywords or ads that can be created per execution. Previously the limit was 250,000.
  • Logging output is truncated at 100kb (unchanged).
  • Quotas for Apps Script services (SpreadsheetApp, MailApp, etc.) are unchanged.
  • Quotas for Google Ads will be enforced as if you were using the API. That is, your script will be subject to API rate limits, but this allows for more flexibility to access more reports or make more changes per execution.

Other changes

The ExecutionInfo no longer exposes getRemainingCreateQuota() or getRemainingGetQuota(), since those quotas no longer apply in the new experience.