A ROAS target in AdOps is a number you compare a live Meta metric against, and the useful version of that number is arithmetic from your own margin rather than a figure copied from a benchmark table. Break-even ROAS equals 1 divided by gross margin. Everything after that is deciding which ROAS field you mean and over how long you measure it.
How do you derive a ROAS target instead of guessing one?
Start at break-even. If gross margin is 35 percent, every Rp 1,000,000 of revenue leaves Rp 350,000 to cover advertising, so advertising breaks even at a ROAS of 1 ÷ 0.35 = 2.86x. At 40 percent margin, break-even is 2.5x. At 60 percent, it is 1.67x.
That single line settles most arguments. A campaign at 2.2x is not “underperforming” in the abstract; at a 35 percent margin it is losing money, and at a 60 percent margin it is comfortably profitable. Two accounts can run the identical creative, the identical audience and the identical ROAS, and one of them should be scaled while the other should be paused.
From break-even you get three numbers, and a rule for each:
- Pause threshold, below break-even, with enough distance that normal variance does not trip it.
- Hold band, straddling break-even, where no rule acts.
- Scale threshold, above break-even by enough that the extra spend still earns margin.
The hold band is the part people skip, and it is what stops a rule set from oscillating between pausing and scaling the same campaign week after week.
Why does this article contain no benchmark table?
Because a benchmark from someone else’s margin structure, market, attribution window and product mix is not a target — it is a number with no denominator. AdOps publishes no ROAS benchmark table for that reason.
The comparison worth making is against your own account: this campaign against the account average, this week against last week, this product against its own target. AdOps supports exactly that shape. A condition can compare one metric against a fixed value, or against another metric measured over its own period — so “today’s ROAS is below the last 7 days’ ROAS” is expressible as a single condition, and it is a far better trigger than any external benchmark.
Which ROAS is AdOps actually showing you?
Two things to keep straight, because they are the most common source of “the numbers do not match”.
In rules, there are two ROAS metrics. Purchase ROAS reads Meta’s omni purchase return. Website Purchases ROAS reads the website pixel purchase return. They have different denominators and will not agree. Pick one per account and write every threshold against that one; a rule set that mixes both is a rule set nobody can reason about.
On the dashboard, two calculations coexist. The Purchase ROAS and Aggregated ROAS cards prefer Meta’s own attributed ROAS fields and send the unified attribution setting, which is why they line up with Ads Manager. The campaign leaderboard and the account comparison compute ROAS from purchase action values instead, so they can differ from the cards. Use the cards for the account-level truth and the leaderboard for ranking, not the other way round.
The cards display to 3 decimal places with an x suffix and carry a badge: Profitable at 1.0 and above, Moderate at 0.5 and above, Low below that. Those badges are about whether revenue exceeds spend, not about whether you are making money — at a 35 percent margin, “Profitable” starts at 2.86x, not at 1.0x.
Over what window should the target be measured?
Long enough to be real, short enough to act on. In practice:
| Decision | Window | Volume gate |
|---|---|---|
| Pause an unprofitable campaign | Last 7 days | Spend over the same window, above your defensible floor |
| Cut a fast failure | Last 3 days | A higher spend floor, because the window is shorter |
| Scale a winner | Last 3 or Last 7 days | Spend floor plus a purchase count, so one large order cannot trigger it |
| Report to a client | This month | None |
Never scale on today. A single large order early in the day can put a campaign at 8x for two hours, and a rule that checks every 15 minutes will find that window.
The dashboard is cached per user and per period for 1 hour, and shows whether what you are reading is live or cached with the time it was last updated. When a decision depends on the current number, use the refresh control rather than the cached one.
How do you keep one target in one place?
Type a target into ten rules and you now maintain ten targets. The alternative is a custom metric: a named metric bound to a Google Sheet, with a lookup column and a value column, resolved at evaluation time.
Put a target_roas column in a sheet keyed by campaign id — or by product, or by margin tier — and point a custom metric at it. Then write the condition as a metric-to-metric comparison: Purchase ROAS, Last 7 days, less than the custom metric. When margins change, you edit the sheet, and every rule that references it moves with you. That is also how seasonal targets get handled without touching a single rule during a promotion.
What breaks a good target?
Three things, all avoidable.
Mixing ROAS definitions across rules. One rule on Purchase ROAS and another on Website Purchases ROAS will contradict each other, and the log will look correct in both cases.
No volume gate. A ROAS threshold with no spend floor is a threshold that fires on noise. Every ROAS condition deserves a Spend condition next to it in the same task.
Scaling with no ceiling. The increase-budget action has a Maximum budget cap field and the set-budget action takes a literal amount or a custom metric. Fill the cap in, pair the task with an action-frequency cooldown, and a ROAS spike raises the budget once rather than every 15 minutes until the account has changed shape overnight. The shipped Tiered Budget Scaling template is a reasonable starting shape for that ladder.