Skip to content

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.

By Gordon Geraghty·MIT Licence·Updated: 24 September 2026·ADVANCED
01 Prerequisites & Architecture
Stage 01 Architecture

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.

Difficulty:Advanced Architecture
Time:20–30 mins
Required Access & Permissions:
Google Ads Admin AccessCampaign Budget Edit Permissions
STEP 01Financial Target Ingress
Monthly Target CapTotal budget target (e.g. $25,000/mo)
STEP 02GAQL Billing Query
Month-to-Date SpendAggregates cost_micros from campaign_budget
STEP 03Pacing Algorithm
Pacing Trajectory ModelerCalculates expected burn rate & day-of-week weight
STEP 04AdsApp Budget Mutate & Webhook
Daily Budget AdjustmentRecalibrates campaign daily caps & sends pacing report
02 Interactive Configurator

Multi-Campaign Google Ads Budget Pacing & Governance System Configurator

Worked Example · Deterministic Calculation

Monthly Budget Pacing & Overspend Shield — GAQL Pacing Governance

Automated pacing and overspend governance across multi-campaign Google Ads portfolios.

1 Input Parameters & Assumptions

ParameterValueContext & Provenance
Monthly Budget Limit$25,000.00 USD / monthTarget monthly spend cap across all enabled campaigns
Evaluation ScheduleDaily 06:00 & 18:00 ScheduleTwice-daily audit check to monitor intraday pacing trajectory
Alert ChannelDiscord Webhook Notification TargetPerformance media governance webhook channel
Automated Emergency BrakeDry Run (Enabled) Governance ActionSimulates 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

Target Monthly Spend Cap$25,000.00Budget CapTotal authorized monthly advertising ceiling
Max Trajectory Threshold115%Pacing IndexWarning triggered if spend trajectory projects month-end overage > 15%
Weekend Protection WindowActiveShield StatusPrevents Google Ads 2x daily budget headroom surges during unmonitored weekends
Computed MetricResultInterpretation & Threshold
Target Monthly Spend Cap$25,000.00 Budget CapTotal authorized monthly advertising ceiling
Max Trajectory Threshold115% Pacing IndexWarning triggered if spend trajectory projects month-end overage > 15%
Weekend Protection WindowActive Shield StatusPrevents Google Ads 2x daily budget headroom surges during unmonitored weekends

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.

INSTRUMENT BOUNDARIES

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 & Automation

Configure 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.

Load Strategy Preset:

Script Template & Destination

Monitors day-of-month spend trajectories across all enabled campaigns and warns when account is projected to exceed monthly caps.

Thresholds & Execution Settings

✓ GAQL Valid

Generated Artifacts Preview

Element 2 (Secondary): Google Ads scheduled backend script (GAQL) with automated alerting to Slack, Teams, Discord, Google Chat, or Email.
/**
 * ============================================================================
 * 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
    }
  ]
};
}
Export & Deployment Actions1-click clipboard transfer, shareable URL hash, and local file downloads.

Built by Gordon Geraghty, Head of Performance MediaZero Data Sent to Server
03 Deployment & Export

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

MCC Daily Pacing Calculation ScriptMccBudgetPacingCalculator.jsjavascript

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')
  };
}
04 QA & Verification Guide

Budget Pacing QA & Trajectory Verification

Verify that projected spend matches planned targets and daily budget adjustments stay within safe bounds.

Pre-Production Verification Checklist

✓
Verify Days-Remaining Calculation

Ensure script accounts for leap years and correct days in current calendar month.

✓
Test Safety Cap Safeguard

Confirm script will never increase a daily campaign budget by more than 25% in a single adjustment.

✓
Verify Daily Pacing Report Delivery

Check Slack or Teams pacing digest for accurate MTD spend, remaining budget, and projected month-end total.

Terminal Diagnostic & Debug Commands

Inspect Account MTD Spend in Google Adsjavascript

Returns exact month-to-date cost for current Google Ads account.

AdsApp.currentAccount().getStatsFor("THIS_MONTH").getCost()

Failure Remediation & Troubleshooting

Issue: Campaign Overspending Month-End Budget by 15%+

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 Licence

This resource is free, open and un-gated under the MIT Open Source Licence. You are encouraged to use, integrate and cite it with attribution:

Geraghty, G. (2026). Multi-Campaign Google Ads Budget Pacing & Governance System. Gordon Geraghty Resources Hub. https://gordongeraghty.com/resources/performance-media/google-ads-budget-pacing-governance
BibTeX Format
@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.