How to Build a Google Ads Daily Pacing Script

Every morning, before anything else, someone on the GrowRoom paid media team would open a budget pacing spreadsheet and review our clients’ budget spent month-to-date vs the target. Next, they’d cross-reference it against the respective Google Ads accounts, and (if the account was not on target), review what campaigns were causing the account to misspend, and investigate why. 

Then they’d develop an internal report notifying the team of which account and campaigns were not on target, why they weren’t, and what we should do about it. Multiply that by every account in the portfolio, every single day, and you can see the problem. It wasn’t a hard task, but a necessary one. 

Keeping client spend on track across a large portfolio of Google Ads accounts is a core part of running paid media. For a long time, that meant doing it manually… until we started automating it with a script that was built and refined over several iterations.


Where This Started

Our performance marketing and media agency, GrowRoom, manages paid media for a range of clients, and as our team and client list grew, I started noticing how much account manager time was being swallowed by manual, repetitive checks – I’d guess most agency owners know this problem. 

Budget pacing was one of the biggest offenders. The process pulled data from Google Ads into a tracking sheet, and someone had to read it, interpret it, validate it against the live account, and write up what it meant for that account.

It was a manual data reviewing task, done by team members who were capable of much more useful things, and as the client list grew, so did the hours it consumed. 

The task took around half an hour every morning; 5 days a week, 20 days a month. That’s 10 hours of manual time spent on a task that needed to be done, but I was sure that this process could be automated and save manual account manager time.

The Problem

The pacing sheet itself wasn’t the problem. Every morning, it told us exactly how each account was spending against the target. Once we knew an account was over or under pace, someone still had to dig into why, and that was the problem. An account manager had to spend time reviewing campaigns, working out what was driving the drift, then writing up a report so the rest of the team knew what was going on and what to do about it.

Spend drifts for all kinds of reasons – demand shifts, auction competition, a CPC creeping up over a few days – and figuring out which one applied to a given account, on a given day, took some real digging. Multiply that across every account in the portfolio, and it added up to hours of manual review every day, on top of the pacing check itself. 

It went beyond the top line number too. The team had no quick way to see which campaigns or ad groups were burning budget inefficiently, or which ones were performing well enough to deserve more of it. Every day, that meant:

  • Reading the pacing data and flagging off-track accounts
  • Reviewing campaign and ad group performance to understand why
  • Writing up a report on what was happening and where to push or pull budget
  • Making the necessary changes

Three of those four steps were purely data analysis and reporting. Only the last one was actual implementation work. 

The Solution

The pacing sheet told us what was happening, but the script needed to explain why. The fix was a Google Ads script, run at MCC level, that did what the budget pacing sheet already did; reads monthly spend, compare against target, and classifies as on pace, overspending, or underspending, suggest avg. daily spend remaining, and then takes it one step further, completing the investigation work the account manager would do manually.

The script looks at the last 30 days of campaign and ad group data, and suggests based on performance where the budget should shift, i.e., toward efficient converters, or away from campaigns, ad groups or keywords which were underperforming. 

The script will review performance at a keyword level, identifying if certain terms are performing above or below a pre-established threshold , as well as review auction insights – identifying if key changes within the competitive landscape are likely the cause of performance shifts, and flag that as part of the report. The full report lands in a shared inbox every morning at 9am. 

The goal was to strip the job down to just two things: QA the report, then act on it.

Data validation, performance review, and report-writing all happen automatically now.

The Implementation

We built the script iteratively, tested in the Google Ads script editor, and refined through real execution logs at each stage. A few things about the setup are important to point out here:

  • A Google Sheet acts as the sole place budgets live, with three columns: Account ID, Client, and Budget.
  • Because it can run at MCC level, one script covers every client account in the specified portfolio. Adding a new client to the pod means adding a row to the sheet, but nothing else changes.
  • Recipient emails and every threshold live in a CONFIG block at the top of the script, so you can tweak the setup without touching the underlying logic.
  • A daily trigger fires the script every morning. Once it’s live, no one has to remember to run it.

What Changed

[screenshot of code from Google Ads code editor including config snippet]

What used to be a manual daily task now happens without anyone touching it.

Logging into multiple accounts, checking spend, calculating pace by hand, writing it all up – all completed before the team are sat at their desks. 

The team gets an email each morning with a summary table across every assigned client, a pacing narrative per account, and specific campaign and ad group recommendations.

Time that used to be funnelled into gathering information now goes into acting on it.

Those 10 hours per month (per pod) is now spent on the work that actually drives performance. Like the higher-level strategic thinking our team needs to progress accounts forward, and the campaign implementation and initiatives that actually have an impact. 


A Few Things Worth Knowing

Rolling this out taught us some important lessons, so here’s what I’d pass on.

Don’t let the script apply budget changes unsupervised. It’s a recommendation engine, not an autopilot, and a human account manager should always be the one implementing changes.

Run it from a dedicated account, not a personal login. Google Ads Scripts send emails from whichever account owns the script, and there’s no way to set a separate sender address, so a shared reporting account keeps things a lot cleaner than tying it to someone’s individual login.

The pacing calculation needs to exclude today’s spend. This one caught us early – if you include the current day, every account looks underpaced each morning simply because today’s budget hasn’t been spent yet. Once we limited the calculation to completed days only, up to 23:59 the day before, that false signal disappeared.

The last one was basic, but just as annoying when it caught us out. Column headers need to match exactly what the script’s looking for, and a case-sensitivity mismatch caused the script to break during early testing. So make sure there’s no silly errors in your column titles. 

If you’re building something similar, Google’s own Ads Scripts documentation is a good starting point for the fundamentals, and their examples library is worth a look before you write anything from scratch.

Scroll to Top