Multi-Campaign Google Ads Budget Pacing & Governance System
Automated pacing projection system and Google Ads MCC script accounting for flight schedules, weekend conversion shifts and approval safety gates.
Google Ads Monthly Budget Pacing Governance Architecture
Tracks month-to-date spend against monthly account caps, accounts for workday vs weekend seasonality curves, projects month-end variance, and dynamically adjusts daily campaign budgets.
Multi-Campaign Google Ads Budget Pacing & Governance System Configurator
Monthly Budget Pacing & Overspend Shield — GAQL Pacing Governance
Automated pacing and overspend governance across multi-campaign Google Ads portfolios.
1 Input Parameters & Assumptions
| Parameter | Value | Context & Provenance |
|---|---|---|
| Monthly Budget Limit | $25,000.00 USD / month | Target monthly spend cap across all enabled campaigns |
| Evaluation Schedule | Daily 06:00 & 18:00 Schedule | Twice-daily audit check to monitor intraday pacing trajectory |
| Alert Channel | Discord Webhook Notification Target | Performance media governance webhook channel |
| Automated Emergency Brake | Dry Run (Enabled) Governance Action | Simulates automatic campaign pausing if budget cap is breached |
2 Explicit Mathematical Formula
Elapsed Month Fraction = Current Day / Days in Month (e.g. Day 20 / 30 = 66.7%)
Target Spend to Date = Monthly Budget Limit ($25,000) × Elapsed Fraction = $16,666.67
Pacing Index = (Actual MTD Spend / Target Spend to Date) × 100
Overspend Alert Condition = Pacing Index > 115% OR MTD Spend > $25,000
Automated Action = Pause non-brand campaigns during weekend if pacing index exceeds 120%3 Computed Output Metrics
| Computed Metric | Result | Interpretation & Threshold |
|---|---|---|
| Target Monthly Spend Cap | $25,000.00 Budget Cap | Total authorized monthly advertising ceiling |
| Max Trajectory Threshold | 115% Pacing Index | Warning triggered if spend trajectory projects month-end overage > 15% |
| Weekend Protection Window | Active Shield Status | Prevents Google Ads 2x daily budget headroom surges during unmonitored weekends |
Multi-Campaign Google Ads Budget Pacing & Governance System — Scope & Limitations
Explicit operational boundaries and constraints defining target use cases and out-of-scope scenarios.
Built For (Target Use Cases)
- Tracking month-to-date Google Ads spend against a monthly budget cap across all enabled campaigns.
- Calculating a pacing index comparing actual spend to a straight-line elapsed-month spend target.
- Alerting via Slack, Teams, Discord, Google Chat or email when trajectory exceeds the overspend threshold.
Not Built For (Limitations & Out-of-Scope)
- Multi-account (MCC) budget governance; the script config targets one Google Ads account ID.
- Automatically pausing campaigns; dry-run mode simulates the brake without editing live budgets.
- Modelling seasonal demand curves beyond a straight-line elapsed-time spend target.
Operational Assumptions & Defaults
- Assumes the monthly budget limit is entered manually and spend accrues evenly across the month.
- Assumes campaign_budget cost data reflects true spend at the time of each scheduled check.
- Webhook destination, account ID and dry-run mode are configured before the script is deployed.
Google Ads Automated Governance Script & Multi-Channel Webhook Builder
Google Ads API & AutomationConfigure production-ready Google Ads scripts with live GAQL linting, dry-run toggles, GTM/GA4 error monitoring tags, and multi-channel webhook formatting for Slack, Microsoft Teams, Discord, Google Chat, and Email alerts.
Script Template & Destination
Thresholds & Execution Settings
Generated Artifacts Preview
/**
* ============================================================================
* Google Ads Governance Automation: Monthly Budget Pacing & Overspend Shield
* Strategy: google-ads-budget-pacing-governance
* Author: Gordon Geraghty - Head of Performance Media (https://gordongeraghty.com)
* Generated:
* ============================================================================
*/
const CONFIG = {
ACCOUNT_ID: "123-456-7890",
WEBHOOK_CHANNEL: "slack",
WEBHOOK_URL: "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX",
NOTIFICATION_EMAIL: "{{EMAIL_ADDRESS}}",
DRY_RUN: false,
ANOMALY_MULTIPLIER: 2.5,
MONTHLY_BUDGET_LIMIT: 15000,
URL_BATCH_SIZE: 50,
GAQL_QUERY: "SELECT campaign_budget.id, campaign_budget.name, campaign_budget.amount_micros, metrics.cost_micros FROM campaign_budget WHERE campaign_budget.status = 'ENABLED' AND segments.date DURING THIS_MONTH"
};
function main() {
Logger.log('Starting Google Ads Governance Script: ' + 'Monthly Budget Pacing & Overspend Shield');
Logger.log('Account ID: ' + CONFIG.ACCOUNT_ID + ' | Dry Run: ' + CONFIG.DRY_RUN);
try {
const report = AdsApp.report(CONFIG.GAQL_QUERY);
const rows = report.rows();
const alertFindings = [];
while (rows.hasNext()) {
const row = rows.next();
if (evaluateRowCondition(row)) {
alertFindings.push(formatFinding(row));
}
}
Logger.log('Total issues / anomalies detected: ' + alertFindings.length);
if (alertFindings.length > 0) {
dispatchAlert(alertFindings);
} else {
Logger.log('All checks passed within normal thresholds.');
}
} catch (err) {
Logger.log('Error executing governance script: ' + err.toString());
}
}
function evaluateRowCondition(row) {
const cost = parseFloat(row['metrics.cost_micros'] || 0) / 1000000;
return cost > (CONFIG.MONTHLY_BUDGET_LIMIT * 0.9);
}
function formatFinding(row) {
return {
campaign: row['campaign.name'] || 'Unknown Campaign',
detail: JSON.stringify(row),
timestamp: new Date().toISOString()
};
}
function dispatchAlert(findings) {
if (CONFIG.DRY_RUN) {
Logger.log('[DRY-RUN MODE] Alerts logged to console only (no webhook dispatched).');
Logger.log(JSON.stringify(findings, null, 2));
return;
}
const payload = buildWebhookPayload(findings);
if (CONFIG.WEBHOOK_CHANNEL === 'email') {
MailApp.sendEmail({
to: CONFIG.NOTIFICATION_EMAIL,
subject: '[ALERT] Google Ads Governance: ' + 'Monthly Budget Pacing & Overspend Shield',
body: 'Issues detected:
' + JSON.stringify(findings, null, 2)
});
Logger.log('Dispatched alert email to: ' + CONFIG.NOTIFICATION_EMAIL);
return;
}
if (CONFIG.WEBHOOK_URL && CONFIG.WEBHOOK_URL.startsWith('http')) {
const options = {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(CONFIG.WEBHOOK_URL, options);
Logger.log('Webhook dispatched to ' + CONFIG.WEBHOOK_CHANNEL + '. Status: ' + response.getResponseCode());
} else {
Logger.log('Warning: No valid WEBHOOK_URL configured.');
}
}
function buildWebhookPayload(findings) {
return {
"text": "*Budget Pacing Alert: Campaign High-Volume Shopping* [CRITICAL]",
"attachments": [
{
"color": "#e01e5a",
"title": "Budget Pacing Alert: Campaign High-Volume Shopping",
"text": "Campaign is projected to exceed its monthly cap of $15000 before month end.",
"fields": [
{
"title": "Month-to-Date Spend ($)",
"value": "11250.0",
"short": true
},
{
"title": "Monthly Cap ($)",
"value": "15000",
"short": true
},
{
"title": "Projected Overspend (%)",
"value": "18.4",
"short": true
},
{
"title": "Account ID",
"value": "123-456-7890",
"short": true
}
],
"footer": "Gordon Geraghty Ads Governance Automation",
"ts": 1748736000
}
]
};
}
Deploy Budget Governance Script
Deploy the pacing script to Google Ads Scripts, configure total monthly target and overspend safety thresholds, and schedule for daily 07:00 AM calibration.
Why Linear Budget Pacing Fails in Enterprise Media
Standard budget pacing templates divide total monthly budget by 30 days, ignoring weekend conversion shifts, promotional flights, and client sign-off delays. This governance model incorporates day-of-week multipliers and safe reallocation boundaries (default plus or minus 20 percent).
Implementation Code & Script
Calculates remaining days, applies weekend multipliers, and models required daily run-rates.
/**
* Multi-Campaign Budget Pacing Calculator (GAQL)
* Author: Gordon Geraghty - Head of Performance Media
* Licence: MIT
* Filter: campaign.status = "ENABLED" AND campaign.serving_status = "SERVING"
*/
function calculatePacing(monthlyTargetDollars, daysInMonth, currentDay, mtdSpendDollars) {
const remainingDays = daysInMonth - currentDay + 1;
const remainingBudget = monthlyTargetDollars - mtdSpendDollars;
const requiredDailySpend = remainingDays > 0 ? remainingBudget / remainingDays : 0;
const expectedPacingRatio = (currentDay / daysInMonth);
const actualPacingRatio = (mtdSpendDollars / monthlyTargetDollars);
const variancePercent = ((actualPacingRatio - expectedPacingRatio) / expectedPacingRatio) * 100;
return {
mtdSpend: mtdSpendDollars,
remainingBudget: remainingBudget,
requiredDailySpend: requiredDailySpend,
variancePercent: variancePercent,
status: Math.abs(variancePercent) < 5 ? 'ON_TRACK' : (variancePercent > 0 ? 'OVERPACING' : 'UNDERPACING')
};
}Budget Pacing QA & Trajectory Verification
Verify that projected spend matches planned targets and daily budget adjustments stay within safe bounds.
Pre-Production Verification Checklist
Ensure script accounts for leap years and correct days in current calendar month.
Confirm script will never increase a daily campaign budget by more than 25% in a single adjustment.
Check Slack or Teams pacing digest for accurate MTD spend, remaining budget, and projected month-end total.
Terminal Diagnostic & Debug Commands
Returns exact month-to-date cost for current Google Ads account.
AdsApp.currentAccount().getStatsFor("THIS_MONTH").getCost()Failure Remediation & Troubleshooting
Cause: Google Ads 2x daily budget surge headroom spent full allocation in first 20 days.
Fix: Implement automated budget reductions as elapsed days cross 75% milestone.
How to cite and attribute this tool
MIT LicenceThis resource is free, open and un-gated under the MIT Open Source Licence. You are encouraged to use, integrate and cite it with attribution:
@misc{geraghty_google_ads_budget_pacing_governance,
author = {Geraghty, Gordon},
title = {Multi-Campaign Google Ads Budget Pacing & Governance System},
year = {2026},
url = {https://gordongeraghty.com/resources/performance-media/google-ads-budget-pacing-governance},
note = {Head of Performance Media, Empire Amplify}
}Changelog & Version History
v1.0.0Initial release with automated daily pacing calculations and sign-off approval controls.
Strategic Takeaway & Operational Guidelines
Google Ads allows smart bidding campaigns to spend up to 200% of daily budgets on high-intent days. Without automated pacing governance, monthly budgets are frequently exhausted in the first 20 days. This script enforces steady trajectory pacing throughout the calendar month.