How to measure marketing ROI for SaaS, channel by channel
Measure SaaS marketing ROI in 6 steps: loaded channel cost, billing-verified revenue, a 12-month window and gross margin, with a worked table for 4 channels.
Muzahid Maruf, FounderUpdated
On this page
Explore with AI
Opens this article inside the chosen assistant with a ready-made prompt.
To measure marketing ROI for SaaS, take a channel's gross profit from billing-verified subscription revenue over a fixed window, subtract the channel's fully loaded cost, and divide by that cost.
The revenue comes from Stripe, Paddle Billing, Polar, Lemon Squeezy, Creem or Dodo Payments, because an ad dashboard only counts the conversions it claims.
A customer who cost $250 to acquire and pays $49/month at an 80% gross margin repays that cost in 6.4 months, and the same arithmetic works for every channel once the inputs are right.
Key takeaways
- Return on marketing is a channel's gross profit over a fixed window such as 12 months, taken from billing revenue after refunds, minus its fully loaded cost, divided by that cost.
- In the worked example four channels blend to 10.3%, yet they range from 84.9% for newsletter sponsorships to a 40.0% loss for paid social, which needs 20 months to repay against a 12-month SMB target.
- An ad dashboard that claims 55 conversions where billing shows 40 paying customers moves CAC from $182 to $250, so the customer count has to come from the billing system.
- The marketing source must reach the invoice: Stripe metadata holds up to 50 pairs with values up to 500 characters, and Safari deletes script-written cookies after 7 days without a visit.
- TrackRev supplies revenue per channel from $29/month but does not import ad spend, so cost, CAC and payback stay in your own sheet.
The SaaS marketing ROI formula
A subscription keeps paying for months, shrinks through refunds and cancellations and grows through upgrades, so retail ROI math needs a window and a margin.
loaded cost = media + fees + creative + tools + commissions + salary shareCAC = loaded cost / new paying customersgross profit = billing revenue in window, after refunds x gross marginROI = (gross profit - loaded cost) / loaded costROAS = billing revenue in window / loaded costpayback = CAC / (monthly revenue per customer x gross margin)ROAS stops at revenue. ROI and payback apply gross margin as well, which is how Bessemer Venture Partners measures CAC payback.
The window matters as much as the margin. On a $49/month plan the first invoice is $49, while a customer who stays 12 months pays $588, so dividing by first-payment revenue undercounts every channel that brings customers who stay.
A lifetime window overshoots, since nobody knows yet what this quarter's customers will pay in year 3. A fixed 12 months sits between the two.
Step 1: Total the full cost of each channel
For each channel add media spend, agency or freelancer fees, creative production, tools used only for that channel, affiliate commissions paid, and the share of salary spent on it.
A marketer on a $90,000 salary who gives 8 of 40 weekly hours to one channel costs it $18,000 a year, or $1,500 monthly.
Check the grand total against a published median. The SaaS Capital 2026 spending benchmarks, from a survey of more than 1,000 private B2B SaaS companies, put median spending at 8% of annual recurring revenue on marketing and 15% on sales.
At $500,000 of ARR, 8% is $40,000 a year, and channel costs that sum to far less deserve a second look for missing lines such as salaries.
Step 2: Count paying customers and revenue from billing
In Stripe a customer is paying when invoice.paid fires and the subscription status is active, as the subscription webhook guide advises. Refunds and disputes arrive as charge.refunded and charge.dispute.created.
Stripe retries a failing webhook for up to 3 days in live mode, so check the stream against the invoice list each month.
Leave the customer count out of the ad platform's report. Google Ads, for example, credits a conversion for 30 days after a click and 1 day after a view by default, and the click window can stretch to 90 days.
Every platform counts on its own, so 2 platforms can claim the same buyer. In the step 5 example the paid search dashboard reports 55 conversions against 40 paying customers in billing, which moves CAC from $182 to $250.
Step 3: Carry the source from the first click to the invoice
Without a source on the billing record there is nothing to attribute revenue with.
Tag every campaign link with UTM parameters (the free UTM builder keeps the spelling consistent), then store them and any click ID from your own server when the visitor lands.
A script-written cookie is the weak point: Safari's Intelligent Tracking Prevention deletes cookies created in JavaScript after 7 days without a visit and caps them at 24 hours when the landing link carries click IDs as URL parameters, so one can vanish before a 21-day trial converts.
At checkout, write the source onto the Stripe objects. Stripe metadata holds up to 50 key-value pairs per object, with keys up to 40 characters and values up to 500, enough for utm_source, utm_medium, utm_campaign and a click ID.
It does not copy between objects by itself. Pass subscription_data.metadata when you create the Checkout Session and it lands on the Subscription, which Stripe snapshots onto each invoice at parent.subscription_details.metadata. The Stripe metadata attribution guide has the full setup.
Step 4: Choose the revenue window and the attribution model
Set the revenue window to the payback you can afford. Bessemer's target is under 12 months for SMB-focused cloud companies, so a self-serve product at $49/month should read 12 months of revenue per customer.
Label the figure "to date" until every customer in the cohort reaches month 12. Keep the click-to-payment window longer than the median days from first click to first payment in billing.
Google Ads defaults to 30 days, which cuts off a sales-led deal that takes 90.
The model decides which channel gets the customer. Last-touch credits the final click, first-touch the first, and linear splits the payment evenly.
A channel that ranks first under last-touch and last under first-touch is harvesting demand others created, and the attribution model comparison shows how rankings shift. Run all 3 on the same customers.
| Model | Podcast link | Newsletter link | Google ad |
|---|---|---|---|
| Last-touch | $0.00 | $0.00 | $49.00 |
| First-touch | $49.00 | $0.00 | $0.00 |
| Linear | $16.33 | $16.33 | $16.33 |
Credit for one $49 first payment from a buyer whose path was a podcast link, a newsletter link and a Google ad, in that order. Linear shares are rounded.
Google Analytics 4 cannot run that comparison. Its attribution reports offer 3 models: data-driven, paid and organic last click, and Google paid channels last click.
First click, linear, time decay and position-based were removed in November 2023, and every remaining model leaves direct visits without credit unless the whole path was direct. First-touch or linear credit has to be computed outside those reports.
Step 5: Calculate ROI, CAC and payback for each channel
Take a hypothetical product at $49/month with an 80% gross margin, so each active customer yields $39.20 of gross profit monthly. One quarter of costs and billing results looks like this.
| Channel | Loaded cost | Paying customers | CAC | 12-month revenue per customer | 12-month ROI | Payback |
|---|---|---|---|---|---|---|
| Paid search | $10,000 | 40 | $250 | $360 | 15.2% | 10.4 months |
| Newsletter sponsorships | $2,700 | 12 | $225 | $520 | 84.9% | 6.5 months |
| Content and SEO | $5,400 | 18 | $300 | $450 | 20.0% | 10.0 months |
| Paid social | $6,000 | 15 | $400 | $300 | -40.0% | 20.0 months |
| All four channels | $24,100 | 85 | $284 | $391 | 10.3% | 10.9 months |
A hypothetical quarter for a $49/month product at an 80% gross margin. Revenue per customer is billing revenue over 12 months, net of refunds, cancellations and upgrades.
The blended row looks acceptable: a 10.3% return and a payback inside 12 months. The channel rows disagree. Newsletter sponsorships return 84.9% and repay in 6.5 months, while paid social loses 40.0% and would need 20.0 months.
Paid search shows a ROAS of 1.44, or $14,400 of revenue on $10,000, yet its return on gross profit is 15.2%, because 20% of every dollar goes to delivering the product.
Step 6: Reconcile to billing and set decision rules
Sum the revenue credited to every channel and compare it with all new-customer revenue in billing for the same period. If billing shows $12,000 and channels explain $9,000, the other $3,000 (25%) has no source.
Direct visits and word of mouth fill part of that bucket, and my rule is to fix capture before comparing channels whenever it passes 20%. Set the payback and lifetime value thresholds before looking at results.
| Source | Benchmark | Figure |
|---|---|---|
| Bessemer Venture Partners | CAC payback targets: SMB-focused, mid-market and enterprise cloud companies | Under 12, 18 and 24 months |
| David Skok | Months to recover CAC at many of the best SaaS businesses | 5 to 7 months |
| David Skok | Lifetime value to CAC at the best SaaS businesses | Above 3 |
Published guidelines for CAC payback and lifetime value. Skok adds that profitability gets thin once recovering CAC takes longer than 12 months.
Against the 12-month SMB line, newsletter sponsorships (6.5 months) and content (10.0) pass, paid search at 10.4 is close, and paid social misses by 8 months, so its budget is the first to cut or rebuild.
Lifetime value needs more than 12 months of data, because it estimates revenue you have not seen. Compute it per channel, as in subscription LTV attribution, before applying the 3-to-1 rule from Skok's SaaS metrics guidelines.
Affiliate and referral programs
The cost is the commission, and a recurring commission keeps adding cost for as long as the customer pays. A 20% recurring commission on a $49/month plan is $9.80 monthly, or $117.60 over a 12-month window, per customer.
Refunds reverse the commission along with the revenue, so the 2 numbers should move together; affiliate refund clawbacks covers the mechanics.
Content and SEO
Customers arrive months after the writing is paid for, so group the 18 customers in the example by the month of their first tracked click and read each cohort after its 12 months.
First-touch credit suits this channel, since an article seldom closes a sale on the same visit.
Newsletter, podcast and video sponsorships
A flat fee buys one placement, so give each placement its own tracked link. A $2,700 sponsorship that produced 12 paying customers has a CAC of $225. Tracking newsletter links to revenue covers the setup.
Why Google Analytics alone cannot close the loop
Google Analytics 4 records browser sessions and whatever events a tag or the Measurement Protocol sends it, while Stripe files payments under customer and invoice IDs.
Closing the loop means carrying the GA4 client ID into Stripe metadata and posting a purchase event from a webhook.
Google says such events should arrive within 48 hours of the browser event, or they may not be processed as expected for conversion attribution.
A first payment after a 14-day trial lands 336 hours after the click and a month-2 renewal about 720, so neither can reliably credit the campaign. The GA4 and Stripe build shows where each piece breaks.
What TrackRev covers and what stays in your sheet
TrackRev is SaaS affiliate software with revenue attribution built in, and that handles the revenue half of the sheet.
It connects to Stripe (with a restricted, read-only key), Paddle Billing, Polar, Lemon Squeezy, Creem and Dodo Payments, and it matches each payment to the tracked click that preceded it by customer email, so there is no checkout code to change.
The Channels page ranks every channel by clicks, conversions and attributed revenue with refunds and chargebacks netted out, and a second table shows all-time revenue per channel, renewals included.
Last-touch is the default, and first-touch or linear is one setting away.
It does not read ad spend. TrackRev has no ad-account connection, so cost, CAC and payback stay in your spreadsheet, divided into the revenue column TrackRev supplies.
Revenue figures need a paid plan from $29/month; the free plan tracks 50 links and 1,000 events per month and hides revenue. The Revenue Attribution page lists the details.
Pick something else if you need ad-account spend pulled in for campaign-level ROAS, or if your billing runs through a processor TrackRev does not connect to.
A team that wants only standalone attribution, with no partner program, may also prefer a dedicated attribution tool.
Found this useful? Share it.
Frequently asked questions
- There is no single percentage, because ROI changes with the window and the margin you choose. A result below 0% means the channel did not return its cost in gross profit by the end of the window. Above 0%, speed matters more than size: a 40% ROI that takes 20 months to arrive can strain cash more than a 15% ROI that arrives in 10. Compare payback with the published target for your segment instead of comparing percentages between companies.
- ROAS divides revenue by cost and ignores margin, so it flatters a product that costs money to deliver. ROI subtracts cost from gross profit before dividing. Take $1 of spend that returns $1.50 of revenue at an 80% gross margin: ROAS is 1.5, gross profit is $1.20, and ROI is 20%.
- Start from the payback you can afford, which is 12 months for most self-serve products, then test it against your own data. A median gap of 21 days between first click and first payment means half your customers pay within 21 days, so a 30-day click window covers more than half of them, and the 90th percentile shows how many it misses. For deals that take 90 days, a 30-day window credits whichever channel touched the buyer last and misses the one that started the conversation.
- Yes. Credit later upgrades to the channel that acquired the account, and subtract downgrades, refunds and cancellations. A $49/month customer who upgrades to $99 in month 4 pays 3 x $49 plus 9 x $99, or $1,038 over 12 months against $588 with no upgrade. A channel whose customers expand can beat one with a cheaper first sale, and only billing data shows it.
- Count the customer at the first paid invoice and keep the trial start date on the same row. Group by the month of the first click: with a 14-day trial, a visitor who clicks on March 28 pays in April, so March spend set against March payments understates March. Wait one trial length after a month ends before reading its cohort.
- No. TrackRev reports revenue per channel from your billing system and never sees ad spend, so you divide its revenue by your own cost figures. Revenue needs a paid plan from $29/month, and the free plan covers link tracking only.

Written by
Founder, TrackRev.io & Contant.io
Muzahid Maruf founded TrackRev.io, SaaS affiliate software with no limit on tracked revenue, and Contant.io. He writes about affiliate programs.
Writes about Marketing attribution · Link tracking · Revenue analytics · SaaS growth
Stop guessing where your revenue comes from.
Set up TrackRev in about five minutes. The free plan covers 1,000 events a month, no card needed.
Start free