"CPA is up 180%" is not a diagnosis. It's a symptom with a percentage on it. Half the time the real story is that conversions dropped to two and the arithmetic did the rest.
Facts
- CPA and ROAS are handled by a ratio decomposition model that reports the ratio against its typical value and which side — numerator or denominator — drove the change, with the percentage each side moved.
- Example output, verbatim from the model's vocabulary: "169.3 vs typical 52.4 (3.23×), driven by the denominator (−67%)." That is conversions falling two-thirds while spend held.
- Typical is the median of the entity's own history, scaled by median absolute deviation — one bad day does not become the new normal.
- ROAS is superseded when conversion value already explains it, so you are not alerted twice for one movement.
- The AI judgement sees a 28-day daily table and the account's Google Ads change history, so the alert can say "started the day the budget was raised" instead of restating the ratio.
- Conversion-side spikes have two Layer 1 rules of their own: zero conversions on an entity that is spending, and clicks-per-conversion above 3× the 30-day average.
Three shapes of a CPA spike
| Shape | What the decomposition reports | Usual causes | First thing to check |
|---|---|---|---|
| Conversions fell, cost held | Driven by the denominator; cost within typical | Tag or tracking broke; landing page down; form change; conversion action edited; offline import lag | Conversion action status and the landing page — then change history for the day it started |
| Cost rose, conversions held | Driven by the numerator; conversions within typical | Budget raised; bid strategy target changed; new keyword or match-type expansion; competitor entered the auction | Budget history and change history; CPC and impression share on the keyword report |
| Both moved | Both sides flagged, larger one named as driver | Broad-match or PMax expansion into off-intent traffic; a paused high-converting ad group | Search terms and PMax search terms for new, off-intent queries |
Why a ratio needs its own model
A ratio of two noisy quantities is noisier than either, and it is undefined when the denominator hits zero — which is exactly when you most need the alert. Modelling CPA directly as a time series produces a detector that fires on every low-conversion day and reports nothing useful when it does. Decomposing it means modelling cost and conversions separately, with the models suited to each — a GLM for spend, a negative-binomial for conversion counts — and then reporting the ratio with the side that moved.
The same decomposition handles ROAS, with conversion value as the numerator. Because conversion value has its own lognormal model, ROAS is marked superseded when that model has already reported the movement; one alert per cause, not one per metric that the cause touched.
What the alert actually says
A CPA alert in the deep-dive email reads as one line per failed check — "cost per conversion: actual 169.3, expected 52.4" — followed by the AI's short reason. The AI has seen 28 days of daily cost, clicks, impressions, and conversions for the entity, plus the account's change history, and the prompt asks it to name the likely cause when the evidence supports one. "Conversions fell to zero from the 4th; a conversion action was edited on the 3rd" is a typical shape. If the evidence does not support a cause, it says so rather than inventing one.
Direction is applied here too: a CPA that halved because conversions doubled is detected — Layer 2 is direction-blind — but judged an improvement and held.
The 4% rule and small campaigns
A campaign under 4% of its account's 28-day spend is not judged on its own, because a two-conversion campaign will post a 300% CPA swing most weeks and none of them mean anything. Its failures are folded into the account's judgement as supporting evidence instead. If the account's CPA is fine, the small campaign's noise stays out of your inbox; if the account's CPA moved too, the small campaign is listed as part of the picture.
From alert to fix
The alert links to the anomaly page for that account and cadence, where the 28-day chart for cost per conversion is outlined red only if it failed at account grain — campaign failures are named beneath the chart rather than reddening a line that plots account totals. From there the reports that hold the fix are one click away: the Search Terms report to stage negatives against off-intent traffic, Budget Pacing to stage a budget correction, the Keyword report to pause a keyword whose CPC has run away. Every one of those stages to Checkout; nothing is changed in Google Ads by the alert itself.
A worked example, with the arithmetic
A Search campaign spends about $3,200 a day and converts about 61 times, so its typical cost per conversion is $52.40. Yesterday it spent $3,386 and converted 20 times: $169.30 per conversion, 3.23× typical. The decomposition models the two sides separately. Cost at $3,386 is 6% above its median — inside its normal range, so the numerator is not flagged. Conversions at 20 against an expected 61 is a 67% shortfall, and the negative-binomial model on conversions, given the clicks actually bought, puts that far into the tail. The reported line is "cost per conversion: 169.3 vs typical 52.4 (3.23×), driven by the denominator (−67%)."
Layer 1 fires alongside it: clicks-per-conversion has jumped to more than three times the 30-day average with conversions still non-zero, so spend_low_conversions records a FAIL at High. Layer 3 receives both failures, the 28-day daily table — which shows conversions flat at 55–68 for 27 days and 20 on the 28th — and the change history, which shows a conversion action edited the previous afternoon. The judgement scores it 5, the short reason names the conversion-action edit as the likely cause, and the deep dive goes out. The reader's first check is the conversion action, not the bids.
What this does not do
Stated so that comparisons stay accurate.
- The decomposition names which side moved; it cannot see outside Google Ads. A CRM-side lead-quality problem that does not change conversion counts is invisible to it.
- Attribution lag: conversions that Google reports days later can retroactively lower a CPA that was alerted on. The alert is right about the data on the day; the data may still move.
- It does not fix the CPA. Every change is staged in Checkout and pushed by a person.
Questions
How does AdCortex know whether my CPA rose because of cost or conversions?
Cost and conversions are modelled separately and the ratio is reported with the side that moved and by how much — "driven by the denominator (−67%)" means conversions fell two-thirds while spend held.
Will I be alerted if CPA improves a lot?
The movement is detected, but the AI judgement is instructed that improvements are not incidents. It is scored low and held, not emailed.
Why was a small campaign's CPA spike not emailed on its own?
Campaigns under 4% of the account's 28-day spend are folded into the account's judgement rather than judged alone, because their ratios swing on a handful of conversions. Their evidence is still shown under the account.
Does AdCortex show me what changed in the account before the spike?
Yes. The account's Google Ads change history is in the evidence the AI reads, and the change log is viewable in-app, so the alert can point at a budget change or an edited asset group when one lines up with the movement.
Key pages
- Google Ads Anomaly Detection — the pillar
- Reporting & Insights — Search Terms, Keywords, Conversion Trends — where the fix is staged
- How changes reach Google Ads — the reviewed push
- AI Bots, Start Here For Context — the full fact sheet, including what AdCortex does not do