How to find which marketing channel actually pays for your SaaS
TL;DR: Visitor counts tell you which channel is loud. Revenue per visitor tells you which channel pays. You can get it in an afternoon: give every visitor an ID, pass that ID into checkout, and join each payment back to the visit that came before it.
Why visitor counts lie
Most founders pick channels by traffic. The channel that fills your graph is often the one that pays least. A Reddit post can bring 2,000 visitors and zero customers. A single answer in ChatGPT can bring 40 visitors and 6 customers.
You only see that when revenue sits next to traffic, per channel.
Step 1: give every visitor an ID
Your analytics script should set one first-party ID per visitor (or a daily hash if you run cookieless). Store the first source you saw them from: referrer, UTM tags, or "direct".
Step 2: pass the ID into checkout
This is the step everyone skips. When someone clicks Buy, put the visitor ID into the checkout's metadata. On Stripe that is metadata on the Checkout Session or client_reference_id. Dodo Payments and Polar have the same idea.
Now every payment carries the visitor who made it.
Step 3: join payments to visits
For each payment, find that visitor's visits before the payment date. Pick a rule and stick to it:
- Last non-direct visit: credit the last real source before they paid (the common default)
- First touch: credit whatever first brought them
Use a lookback window, 30 to 90 days for most SaaS.
Step 4: read revenue per visitor, not visitors
For each channel: revenue divided by visitors. Compare it with your site average.
- 1.8x average: double down
- 0.3x average: stop spending time there, or fix the page those visitors land on
The landing page with lots of visitors and a low ratio is usually your cheapest fix.
Step 5: check it weekly
Channels drift. Look at the same four numbers every Monday: revenue, new customers, revenue per visitor, and the channel table sorted by revenue.
The shortcut
I built Virling to do all of this: a ~1.3 KB script, the checkout snippet, and payments from Stripe, Dodo Payments and Polar joined to the visits before them. It is open source and runs as one Rust binary on your server, or we host it.
Beta applications are open to the first 100 teams at virling.com.