Manager Account Scripts and executeInParallel
Manager scripts iterate accounts sequentially or run executeInParallel across up to 50 accounts, with a 60 minute ceiling when a callback is specified. The parallel function is isolated, returns a string capped at 10 MB, and isolates failures per account.
A manager-level script sees every account under the manager and runs one body of logic across all of them. It is how agency reporting stops being a Monday morning ritual. It is also the fastest way to write something that works on nine accounts and breaks on the tenth for a reason you did not anticipate.
Sequential or parallel
The simple pattern iterates accounts in turn:
const it = AdsManagerApp.accounts()
.withCondition('Impressions > 0')
.forDateRange('LAST_30_DAYS')
.get();
while (it.hasNext()) {
AdsManagerApp.select(it.next());
processAccount();
}
Readable, easy to debug, and bounded by the same thirty-minute limit as any other script. Fine up to roughly a dozen accounts with light logic.
Beyond that, executeInParallel runs the same function across accounts concurrently. Google allows up to 50 accounts per call, each processAccount can return up to 10 MB to the callback, and specifying a callback raises the execution ceiling to 60 minutes.
The constraints that shape parallel code
The parallel function is isolated. It cannot see variables from the outer scope. Configuration has to be passed in as a string argument, or read from a spreadsheet inside each execution.
It returns a string. Structured data goes through JSON.stringify() and comes back through JSON.parse() in the callback.
Return aggregates, not rows. Ten megabytes disappears quickly if each account returns raw records. Each account should return a summary object; the callback assembles the report.
Failures are isolated per account. This is the main operational reason to prefer it. One account that throws does not stop the other forty-nine, and the callback receives its failure alongside everyone else’s results.
What breaks across accounts
| Difference | Symptom | Handling |
|---|---|---|
| Currency | Totals summed across accounts are meaningless | Report per account, or convert explicitly with a rate you control |
| Time zone | “Yesterday” is a different day in different accounts | Compute dates inside each account using its own time zone |
| Conversion action names | Logic keyed to a name silently matches nothing | Key on category or on a naming convention you enforce |
| Campaign naming | Filters by name work in some accounts only | Use labels, which you can standardise, rather than names |
| Accounts with no spend | Divide-by-zero, empty reports, noise | Filter on impressions in the account selector |
Write the logic as a single-account script, get it correct there, then wrap it. Debugging a manager script that fails on one of forty accounts, in parallel, with no stack trace, is an unpleasant way to discover a null check was missing.
Reporting patterns that hold up
One email, all accounts, sorted by severity. Forty emails at 07:00 do not get read. One email with the three accounts that need attention at the top does.
Append to a Sheet, one row per account per day. This gives you history for free, and history is what makes trend and baseline comparison possible later.
Report accounts that failed as loudly as accounts with problems. An account missing from the report because its execution threw looks identical to an account with nothing wrong. List it explicitly.
When the manager script is the wrong tool
If the logic needs genuine per-client variation, a manager script becomes a nest of conditionals keyed to account IDs. At that point either standardise the accounts, or move the reporting to the Google Ads API, where per-client configuration belongs in a database instead of a switch statement.
Questions
- How many accounts can executeInParallel handle?
- Up to 50 accounts per call. Each processAccount function can return up to 10 MB of data to the callback.
- How long can a manager script run?
- Thirty minutes normally. Using executeInParallel with a callback method raises the ceiling to sixty minutes.
- Can the parallel function see my configuration variables?
- No. It runs in isolation and cannot access the outer scope. Pass configuration in as a string argument or read it from a spreadsheet inside each execution.
- What is the most common cross-account bug?
- Logic keyed to a conversion action or campaign name that exists in most accounts but not all. It matches nothing and produces an empty result rather than an error.