# Calculating marketing ROI when the payback takes months

> The standard ROI formula assumes revenue arrives at once, which is wrong for subscriptions. Use gross-margin-adjusted contribution over a fixed window, and report CAC payback period alongside it - for a bootstrapped business, when the money comes back matters more than how much.

Source: https://rankcert.com/blog/how-to-calculate-roi-on-marketing
Published: 2026-08-29 · Updated: 2026-09-01

---


The textbook formula is:

```
ROI = (revenue − cost) ÷ cost
```

Spend $1,000, earn $3,000, ROI is 200%. Fine for a one-off transaction. Wrong for anything with a subscription attached, for three reasons.

## Why it breaks

**Revenue arrives over time.** A customer acquired for $200 paying $50 a month has produced $50 by the end of the first month. The naive calculation says you lost 75% and it is a disaster. By month twelve the same customer looks spectacular. Both readings are artefacts of when you looked.

**Revenue is not margin.** $50 of revenue at 75% gross margin is $37.50 of contribution. Using revenue overstates every channel by whatever your hosting, payment fees and support cost.

**Spend and result are in different periods.** Content published in January produces customers in June. Dividing June revenue by June spend measures nothing.

## What to use instead

### Contribution over a fixed window

Pick a window - 12 months is standard - and compute:

```
Contribution = customers acquired
             × monthly revenue
             × gross margin %
             × expected months retained (capped at the window)
```

Then `(contribution − spend) ÷ spend`.

The cap matters. Uncapped, you are projecting years of revenue from customers you acquired last week, and the projection is dominated by a churn estimate you do not have enough data for.

### CAC payback period

```
CAC ÷ (monthly revenue × gross margin %)
```

$200 CAC, $50 revenue, 75% margin → **5.3 months** until that customer has paid for themselves.

For a business funding growth from revenue, this is the number that decides whether you can spend more. Under 12 months is healthy for SMB self-serve; over 18 means you need capital to grow at all.

A channel with excellent long-run ROI and a 20-month payback can still bankrupt you before the returns arrive.

## Attribution you cannot resolve

Someone reads a blog post, forgets it, sees a mention two months later, searches your brand name and signs up. Last-click attributes it entirely to branded search. First-click attributes it entirely to the post. Both are wrong.

Rather than buying an attribution model you will not trust:

**Segment by channel and compare rates, not totals.** Branded search converting at 20% and cold organic at 2% is a real, usable difference regardless of the model.

**Watch the branded-search trend.** Brand searches rise when awareness work is landing. It is the cleanest available proxy for the effect of everything unattributable.

**Run holdouts where you can.** Pause a channel for a month and watch what happens to the total. Blunt, and more honest than any model.

Free tool: [UTM Builder](https://rankcert.com/tools/utm-builder) - Build tagged campaign URLs with consistent utm_source, utm_medium and utm_campaign values so your launch traffic is actually attributable.

Tagging every link consistently is the precondition for any of this. Without it you are reasoning about a "direct" bucket that contains everything.

## A worked example

$2,000 on content in Q1. By Q4, 40 customers attributable to organic search, $40/month each, 80% gross margin, average 14 months retained.

```
Contribution = 40 × 40 × 0.80 × 12 (capped) = $15,360
ROI = (15,360 − 2,000) ÷ 2,000 = 668%
Payback = 2,000 ÷ (40 × 40 × 0.80) = 1.6 months
```

Both numbers are needed. The ROI says the channel works. The payback says you can afford to do it again immediately, which is the decision you actually have to make.

<Callout>
If a channel's payback period is longer than your runway, its ROI is irrelevant. Calculate payback first and only look at ROI for the channels that survive it.
</Callout>

<Cta />
