Detection: Campaign hitting daily budget cap while sibling underspends
Key: budget_capped_alongside_underspend
Severity: High
Confidence: 70–85%
What this detection looks for
We flag a pair of campaigns when one is consistently hitting its daily budget cap while a sibling campaign in the same account is consistently underspending against its cap. The detection fires one finding per (capped, underspending) pair.
A campaign is "capped" when all of these are true:
- It is active
- It has a daily budget set
- It has observed spend on at least 5 days in the audit date range
- On at least 60% of those days, daily spend was ≥ 95% of the daily budget
- It hit the cap on at least 5 days total
A campaign is "underspending" when all of these are true:
- It is active
- It has a daily budget set
- It has observed spend on at least 5 days in the audit date range
- Average daily spend was below 60% of the daily budget
Why this matters
When one campaign is regularly hitting its cap, Meta's delivery system is telling you it would spend more if you let it — usually because the audience is converting well at the bid price. Meanwhile a sibling campaign that can't spend its budget is competing for impressions and losing, or targeting an audience Meta can't profitably reach at scale.
Reallocating budget from the underspender to the capped campaign is one of the highest-leverage changes you can make in an account. It almost always increases account-level ROAS in the next 7–14 days.
How we calculate confidence
| Condition | Confidence |
|---|---|
| Capped campaign hits cap on ≥ 80% of days AND underspender averages ≤ 50% of its budget | 85% |
| Both signals present but weaker (cap-hit ≥ 60% OR underspend > 50%) | 70% |
| Neither signal meets minimums | We don't surface the finding |
How we calculate the estimated monthly cost
We estimate the recoverable amount as the daily headroom on the underspending campaign — the difference between its daily budget and its average daily spend — projected to a 30-day month.
monthly_recoverable = (underspender_daily_budget − underspender_avg_daily_spend) × 30
We deliberately do not estimate "uncapped scaling" on the capped campaign, because that requires a counterfactual we cannot observe. The number we show is what you are demonstrably leaving unused today.
What would change our mind
A budget-capped vs. underspending finding can be a false positive in a small number of cases:
- The two campaigns serve different stages of the funnel. A retargeting campaign at its cap and a prospecting campaign underspending is not necessarily waste — the retargeting cap may be a deliberate ceiling on a small high-intent audience. We'd want to confirm the campaign roles before acting.
- The underspender just launched. A campaign that has been live for less than 7 days will look like it is underspending while Meta is still in the learning phase. We require ≥ 5 days of observed spend but you should still ask whether the campaign has had time to ramp.
- Bid strategy differs. A campaign on a cost-cap or bid-cap strategy may be deliberately under-spending because the auction cost exceeds the cap. Removing budget here will not redirect demand — it will only free dollars that may end up unspent elsewhere.
How to fix it
- Open the underspending campaign in Meta Ads Manager
- Reduce its daily budget to a level that matches its actual delivery (e.g., set it to ~120% of the campaign's average daily spend)
- Increase the capped campaign's daily budget by the freed amount — start with a 20% step rather than the full reallocation, so Meta's learning doesn't reset
- Wait 5–7 days, then re-audit. If the capped campaign is still hitting cap, step up another 20%
What we look at to make this detection
effective_statusanddaily_budget_centson each campaignspendinsights metric per day per campaign, summed across the audit date range- We do not use lifetime budgets, CBO sub-ad-set spend, or bid strategy metadata in this detection. Those are explicitly excluded — see "What would change our mind" above for the rationale
Source
This methodology page is generated from
apps/api/app/services/detections/budget_capped_alongside_underspend.py.
The detection code is open for inspection. We do not have hidden rules.