ROAS analysis tutorial: building the real number
most solopreneurs running paid ads look at the platform-reported ROAS in Meta or Google Ads and treat it as truth. the platform shows 4.2x and they think the campaign is winning. then a month later, they cannot reconcile the number with their actual bank balance because Stripe revenue is half what Meta said it should be.
the gap is real. platform ROAS counts conversions Meta or Google attributes to itself, often double-counting cross-channel buyers. true ROAS counts only revenue you actually received, divided by spend you actually paid, with returns and refunds backed out. the gap between the two is usually 30-60%.
this tutorial walks you through calculating true ROAS using a realistic 14-row sample dataset of weekly campaign spend and revenue. by the end, you will know how to spot the gap, segment ROAS by campaign and creative, and decide which campaigns deserve more budget. no Triple Whale, no Hyros, just spreadsheets and 25 minutes.
the sample dataset
below is the dataset we will use. paste into Google Sheets, save as roas-analysis-2026, and follow along.
| week | campaign | spend | impressions | clicks | platform_conversions | platform_revenue | actual_orders | actual_revenue | refunds |
|---|---|---|---|---|---|---|---|---|---|
| 2026-01-06 | meta_retarget | 800 | 42000 | 540 | 28 | 2240 | 22 | 1760 | 80 |
| 2026-01-06 | meta_prospect | 1200 | 88000 | 1100 | 18 | 1440 | 12 | 960 | 120 |
| 2026-01-06 | google_search | 600 | 14000 | 380 | 16 | 1280 | 14 | 1120 | 0 |
| 2026-01-13 | meta_retarget | 850 | 44000 | 580 | 30 | 2400 | 24 | 1920 | 100 |
| 2026-01-13 | meta_prospect | 1300 | 92000 | 1180 | 20 | 1600 | 13 | 1040 | 80 |
| 2026-01-13 | google_search | 650 | 15000 | 410 | 18 | 1440 | 16 | 1280 | 0 |
| 2026-01-20 | meta_retarget | 900 | 47000 | 620 | 33 | 2640 | 25 | 2000 | 160 |
| 2026-01-20 | meta_prospect | 1400 | 95000 | 1220 | 19 | 1520 | 11 | 880 | 80 |
| 2026-01-20 | google_search | 700 | 16000 | 440 | 20 | 1600 | 17 | 1360 | 0 |
| 2026-01-27 | meta_retarget | 950 | 49000 | 660 | 35 | 2800 | 27 | 2160 | 80 |
| 2026-01-27 | meta_prospect | 1500 | 100000 | 1280 | 22 | 1760 | 12 | 960 | 200 |
| 2026-01-27 | google_search | 750 | 17000 | 470 | 22 | 1760 | 19 | 1520 | 0 |
| 2026-02-03 | meta_retarget | 1000 | 51000 | 700 | 36 | 2880 | 28 | 2240 | 120 |
| 2026-02-03 | google_search | 800 | 18000 | 500 | 24 | 1920 | 21 | 1680 | 0 |
ROAS analysis is the calculation of revenue returned per dollar of ad spend. platform-reported ROAS uses the ad platform’s attribution and consistently overstates by 30-60% due to double-counting and last-click bias. true ROAS uses revenue actually received from your billing system, net of refunds, divided by ad spend actually paid. the standard solopreneur build calculates both, computes the gap, and segments by campaign type. it takes 25 minutes in Sheets and consistently surfaces a single campaign-level reallocation worth 20-40% improvement in real return.
step 1: calculate platform ROAS
platform ROAS is what the ad platform shows you. easy version first.
formula in column K (platform_roas):
=G2/C2
expected output for week 1 meta_retarget: 2240/800 = 2.80.
drag down. summary by campaign:
| campaign | spend | platform_revenue | platform_roas |
|---|---|---|---|
| meta_retarget | $5,500 | $14,800 | 2.69 |
| meta_prospect | $5,400 | $7,840 | 1.45 |
| google_search | $4,500 | $9,600 | 2.13 |
| total | $15,400 | $32,240 | 2.09 |
at 2.09x platform ROAS, the campaigns look profitable. let us check.
step 2: calculate true ROAS
true ROAS uses revenue your billing system actually saw, net of refunds.
formula in column L (net_revenue):
=I2-J2
formula in column M (true_roas):
=L2/C2
expected output for week 1 meta_retarget: (1760-80)/800 = 2.10.
summary by campaign:
| campaign | spend | net_actual_revenue | true_roas |
|---|---|---|---|
| meta_retarget | $5,500 | $11,440 | 2.08 |
| meta_prospect | $5,400 | $3,360 | 0.62 |
| google_search | $4,500 | $6,960 | 1.55 |
| total | $15,400 | $21,760 | 1.41 |
true ROAS is 1.41 vs platform ROAS of 2.09. the gap is 32%, which means you lose roughly $0.32 of every claimed dollar to attribution bias and refunds.
common mistake: most solopreneurs report platform ROAS to themselves and treat it as profit. they spend 2x what they should because they think margins are 2x what they actually are. always reconcile to bank deposits monthly.
step 3: identify the attribution gap
build a third calculated column.
| campaign | platform_roas | true_roas | gap |
|---|---|---|---|
| meta_retarget | 2.69 | 2.08 | -22.7% |
| meta_prospect | 1.45 | 0.62 | -57.2% |
| google_search | 2.13 | 1.55 | -27.2% |
meta_prospect overstates ROAS by 57%. that is the campaign Meta is claiming credit for sales that came from elsewhere (probably retargeting, organic, or word of mouth).
google_search overstates by 27%. some of that is intent-based double counting (people Google your brand name after seeing a Meta ad).
meta_retarget overstates by 23%. retargeting is naturally last-click biased.
the gap order tells you which platforms you should trust the least. always discount their numbers by the historical gap when planning future spend.
step 4: calculate margin-adjusted ROAS
ROAS is gross revenue divided by spend. it ignores cost of goods sold (COGS), payment processing fees, and your time. for ecommerce, this matters a lot.
assume:
– COGS = 35% of revenue
– payment processing = 3% of revenue
– contribution margin = 62%
margin-adjusted ROAS:
margin_roas = true_roas × 0.62
| campaign | true_roas | margin_roas |
|---|---|---|
| meta_retarget | 2.08 | 1.29 |
| meta_prospect | 0.62 | 0.38 |
| google_search | 1.55 | 0.96 |
| blended | 1.41 | 0.87 |
at 0.87x margin-adjusted ROAS, the campaign portfolio is losing money even before accounting for fixed costs (your time, software, etc.).
meta_retarget is the only campaign that breaks even at margin. meta_prospect loses 62 cents per dollar. google_search just barely covers itself.
this is the calculation almost no solopreneur runs, and it is the calculation that most often reveals “we are not actually profitable on ads.”
step 5: calculate breakeven ROAS
breakeven ROAS is the ROAS you need to hit to not lose money.
breakeven_roas = 1 / contribution_margin
with 62% margin, breakeven ROAS = 1.61.
| campaign | true_roas | breakeven | profit_or_loss_per_dollar |
|---|---|---|---|
| meta_retarget | 2.08 | 1.61 | +$0.29 |
| meta_prospect | 0.62 | 1.61 | -$0.61 |
| google_search | 1.55 | 1.61 | -$0.04 |
now you have actionable thresholds. retarget is winning by 29 cents per dollar. prospect is losing 61 cents. search is essentially flat.
reallocation rule: shift budget from any campaign below breakeven to any campaign above. if no campaign is above breakeven, you have a margin or pricing problem, not an ad problem.
step 6: blend with LTV for true contribution
the calculation above assumes a transactional business. for SaaS or subscription, customers acquired via ads contribute MRR over their lifetime, not just first-month revenue. blend with LTV.
ltv_adjusted_roas = (first_month_revenue + projected_remaining_ltv) / spend
if your LTV/CAC analysis shows ads-acquired customers have $400 LTV (vs $250 first-month revenue), and you spend $600 to acquire one, your real ROAS over time is 400 / 600 = 0.67, not the platform’s 1.0.
our customer lifetime value calculation tutorial covers the LTV math.
comparing ROAS measurement approaches
| method | source of truth | accuracy | effort |
|---|---|---|---|
| platform ROAS | Meta/Google attribution | low (overstates 30-60%) | zero (it shows it to you) |
| true ROAS (Stripe match) | billing system | medium-high | 25 minutes/week |
| margin-adjusted ROAS | billing + COGS | high | 30 minutes/week |
| MMM (media mix model) | regression on weekly data | very high | requires 6-12 months of data |
| incrementality test | holdout regions or audiences | highest | requires 4-8 weeks per test |
solopreneurs should use true ROAS plus margin-adjusted ROAS. MMM is for $20K+/month spend.
our marketing funnel analysis tutorial covers the funnel where ad-driven traffic enters, and our building a sales tracker in Google Sheets tutorial covers the closed-won pipeline that this ROAS analysis ultimately feeds.
step 7: build the dashboard
create a fresh tab dashboard. paste these as a summary block:
| campaign | spend | true_revenue | true_roas | margin_roas | verdict |
|---|---|---|---|---|---|
| meta_retarget | $5,500 | $11,440 | 2.08 | 1.29 | scale |
| meta_prospect | $5,400 | $3,360 | 0.62 | 0.38 | kill or fix |
| google_search | $4,500 | $6,960 | 1.55 | 0.96 | hold |
| total | $15,400 | $21,760 | 1.41 | 0.87 | net loss |
verdict logic:
– margin_roas > 1.5: scale
– margin_roas 1.0-1.5: hold
– margin_roas < 1.0: kill or fix
add a line chart showing weekly true ROAS by campaign. trendlines tell you which campaigns are decaying (creative fatigue) and which are stable.
frequently asked questions
how do I match Stripe revenue to ad campaigns?
UTM parameters in your ad URLs (utm_source=meta&utm_campaign=retarget) tagged into Stripe metadata at checkout. or, simpler: weekly reconciliation where you total Stripe revenue and apportion to campaigns by claimed share. our GA4 for non-marketers guide covers UTM setup.
what about view-through conversions?
ignore them. view-through (someone saw the ad, did not click, bought later) is the largest source of platform ROAS inflation. only count click-through conversions for true ROAS.
should I use 1-day or 7-day attribution?
shorter is more accurate. 1-day click-through matches reality best for impulse-buy products. 7-day click-through inflates by 20-40%. always know which window you are reading.
my margin ROAS is below breakeven. what next?
three options: raise prices, lower COGS (rare for digital products), or kill the campaign. solopreneurs almost always need to raise prices first; they tend to underprice by 30-50%.
how often should I run this analysis?
weekly during active spend, monthly during steady-state. catch decay quickly; ROAS often decays 10-20% over 30 days due to creative fatigue.
conclusion: reconcile to bank deposits this week
ROAS is the metric solopreneurs trust most and check least. the platform numbers feel authoritative because they come from the same dashboard you use to manage spend. they are not. they overstate by 30-60% on average.
start this week. export weekly spend by campaign, weekly net revenue from Stripe by campaign, plug into the schema above, and calculate true ROAS and margin ROAS. the gap between platform and true is your blind spot. the campaigns below breakeven are your reallocation targets.
if you only have 25 minutes, do this: weekly Stripe export, paste into spend table, calculate true ROAS, mark anything below 1.6 for review. that single workflow has changed more solopreneur ad budgets than any dashboard tool sold for $200/month.
for context on what to fund instead, our customer lifetime value calculation tutorial covers the LTV side of the LTV/CAC equation, and our marketing funnel analysis tutorial covers the conversion math downstream of ad-driven traffic. cut the leak, then redirect.