"ROAS is at 300%, so we're profitable." I've watched this sentence get accepted in marketing meetings, signed off on slides, and used to justify scaling spend — and then watched the same campaigns produce a money-losing month-end P&L.
The bug is small but expensive: ROAS at 3x ad spend can still lose money once gross margin enters the picture. ROAS 100% is not breakeven, and using it as a mental shortcut for "we recovered the ad spend" is the most common ad-ops mistake I see in Japanese SMB EC.
This post lays out the fix: derive breakeven ROAS from gross margin, then pair ROAS with RPS (Revenue Per Session) so you can judge both efficiency and scale. Both ideas take five minutes to internalize and durably change how you allocate ad budget.
TL;DR
- ROAS = Ad-driven Revenue / Ad Spend x 100%. Revenue-based, not profit-based — gross margin is not in the formula.
- ROAS 100% is not breakeven. The real bar is Breakeven ROAS = 1 / gross margin x 100%. At 30% margin, that's 333%. At 50%, it's 200%. At 10% (thin-margin retail), it's 1,000%.
- ROAS alone hides scale. ROAS 500% on a campaign that drives 10 sessions/month is a rounding error. Pair ROAS with RPS so "efficiency" and "scale" land on the same screen.
Why ROAS 300% can still be a loss
The standard ROAS formula is:
ROAS = Ad-driven Revenue / Ad Spend x 100%
The numerator is revenue, not profit. Revenue still has cost of goods, shipping, and payment fees baked in. So ROAS 100% means "revenue roughly equals ad spend" — which leaves you with whatever the gross margin lets through, and nothing else.
Worked example: 30% gross margin, $1,000 ad spend, $3,000 revenue (ROAS 300%).
- Gross profit = 3,000 x 30% = $900
- Ad spend = $1,000
- Net result: $100 loss
ROAS 300% on a 30%-margin product is a loss. The mental model "ROAS x means I made x times my ad spend" treats ROAS as if it were ROI. It isn't.
Breakeven ROAS = 1 / gross margin x 100%
Once you accept that gross margin is the missing variable, the fix is mechanical:
Breakeven ROAS = 1 / Gross Margin x 100%
| Gross Margin | Breakeven ROAS | Ad Spend $1,000 → Required Revenue |
|---|---|---|
| 10% | 1,000% | $10,000 |
| 20% | 500% | $5,000 |
| 30% | 333% | $3,333 |
| 40% | 250% | $2,500 |
| 50% | 200% | $2,000 |
| 60% | 167% | $1,667 |
A few patterns fall out immediately:
- Thin-margin verticals (food, low-ticket D2C around 10-20%) need ROAS in the 500-1,000% range just to break even. "ROAS 400% campaign performing well" reads completely differently here than at 50% margins.
- Mid-margin EC (general retail, electronics around 20-30%) lands at 333-500% breakeven. Industry-average ROAS quotes of "300-500%" sit dangerously close to the loss line.
- High-margin verticals (cosmetics, branded apparel at 50-70%) can survive at 167-200% ROAS. Aggressive customer-acquisition campaigns make sense here in a way they don't elsewhere.
The single most useful thing I've done as a result of this is to set target ROAS = breakeven ROAS x 1.2 — a 20% margin of safety above the loss line. For a 30%-margin product that's 333% x 1.2 = 400% as the operating target, not "300-500% because that's what the industry quotes."
If your ad team can't tell you the gross margin off the top of their head when they hand you a ROAS report, that's the gap to close before any other optimization.
Why ROAS alone misjudges ad budget
The second failure mode is subtler. Compare two campaigns running at the same $1,000 monthly ad spend:
- Campaign A: ROAS 500%, 10 sessions/month, $5,000 in revenue
- Campaign B: ROAS 250%, 500 sessions/month, $25,000 in revenue
Pure ROAS ranking puts A at 2x B. But B is doing 5x the revenue. ROAS measures efficiency; it cannot measure scale. If you allocate budget by ROAS alone, you systematically over-fund efficient-but-tiny campaigns and under-fund larger campaigns that are doing the actual revenue work.
The fix is RPS (Revenue Per Session) = Revenue / Sessions, paired with ROAS in a 2x2:
| State | Decision |
|---|---|
| High ROAS x High RPS | Winning channel — scale budget |
| High ROAS x Low RPS | Room to grow scale — expand audience / bidding |
| Low ROAS x High RPS | Ad spend too high — optimize bids / creative |
| Low ROAS x Low RPS | Channel mismatch — stop or rebuild |
ROAS asks "how efficient is each ad dollar?" RPS asks "how productive is each session?" Together, they cover both axes that matter for budget allocation. ROAS without RPS leaves you blind to scale; RPS without ROAS leaves you blind to ad cost.
The mental model: Revenue = ROAS x Ad Spend = RPS x Sessions
Once you have both metrics in place, ad operations collapse into a clean dual-equation:
Revenue = ROAS x Ad Spend (ad investment lens)
Revenue = RPS x Sessions (traffic and efficiency lens)
Every initiative ultimately moves one of these levers:
- Ad spend up → sessions up → scale grows (assuming RPS holds)
- Targeting refinement → ROAS up → efficiency improves
- LP / UX optimization → CVR up → RPS up
- AOV plays (bundles, free-shipping thresholds) → AOV up → RPS up
When initiatives are framed by which lever they move, prioritization gets a lot easier. "We're improving the LP" → that's an RPS bet, judge it on RPS lift. "We're expanding the keyword list on a winning campaign" → that's a sessions bet, judge it on absolute revenue, not ROAS preservation.
This is the lens we built RevenueScope around: open the dashboard and Revenue / RPS / AOV / CVR / ROAS for every channel sit on a single screen, with the gross-margin-aware breakeven line visualized so "ROAS 300% reads as profit" stops happening. The tool is opinionated about it — Revenue First, ad-spend decisions made against gross-margin-aware breakeven, not industry-average ROAS quotes.
A practical checklist before your next ad-budget meeting
- Document your gross margin by SKU group or campaign group. Even rough numbers beat "we don't know."
- Compute breakeven ROAS = 1 / gross margin x 100% for each segment.
- Set target ROAS = breakeven ROAS x 1.2 (or higher if your CFO is conservative).
- Add RPS to the dashboard alongside ROAS for every channel.
- Use the 2x2 (ROAS x RPS) to decide scale / optimize / stop, not raw ROAS rankings.
The cost of doing this is one spreadsheet and a willingness to retire "ROAS 300% = profitable" from team vocabulary. The upside is that ad-budget allocation stops being a coin flip on margin-blind metrics.
Question for the dev.to crowd: When you've handed off margin-aware ROAS to a non-finance ad team, what slowed adoption? Mine has been "but the platform shows ROAS 300% as green" — the visual reinforcement of the wrong threshold is a real problem. Curious how others have unhooked teams from the platform's default reading.
Top comments (0)