How to calculate true startup CAC with organic traffic
Meta description: Learn the difference between blended and paid CAC, avoid misattributing organic signups to paid channels, and use practical SQL queries to make smarter ad-spend decisions.
TL;DR
Most startups calculate a single CAC number by dividing total marketing spend by total new customers. This “blended CAC” hides a real distortion: organic signups subsidize your paid channel economics, making paid acquisition look cheaper than it actually is. The fix is separating blended CAC from paid CAC, enforcing strict UTM discipline, implementing server-side attribution, and running cohort-level SQL analysis. Below is the framework, the formulas, and the queries to do it without enterprise tooling.
The Healthchecks.io lesson: know your real costs
The recent Hacker News discussion around Healthchecks.io moving to self-hosted object storage is a good reminder: small teams and solo founders who understand their true cost structures make better infrastructure and growth decisions. The same rigor that drives a bootstrapped service to evaluate self-hosted storage over managed providers should drive how you evaluate every dollar spent on acquisition.
Yet most early-stage teams get this wrong.
Blended CAC vs. paid CAC: the numbers that mislead you
Most teams compute one number:
Blended CAC = Total Marketing Spend / Total New Customers
If you spent $5,000 last month and acquired 500 customers, your blended CAC is $10. Looks healthy. But what if 350 of those customers came from organic search, direct traffic, and word-of-mouth, channels you spent $0 to acquire?
Paid CAC = Paid Channel Spend / Paid-Attributed Customers
Paid CAC = $5,000 / 150 = $33.33
That changes the decision calculus entirely.
| Metric | Formula | Example Value | What it tells you |
|---|---|---|---|
| Blended CAC | Total spend / all new customers | $10.00 | Overall efficiency (misleading in isolation) |
| Paid CAC | Paid spend / paid-attributed customers | $33.33 | True cost of buying a customer |
| Organic ratio | Organic customers / total customers | 70% | How dependent you are on free channels |
| CAC distortion factor | Paid CAC / Blended CAC | 3.3x | How much organic subsidizes your numbers |
A CAC distortion factor above 2x means your blended number is functionally useless for ad-spend decisions. I’ve seen teams scale paid spend based on blended CAC, only to discover their actual unit economics were underwater once organic growth plateaued. It’s a painful lesson, and it usually hits right when cash is getting tight.
The attribution stack for small teams
You don’t need Segment, a CDP, or a data warehouse to get this right. The minimal stack looks like this:
1. Strict UTM discipline
Every paid link gets tagged with utm_source, utm_medium, and utm_campaign. Enforce this at the process level. No UTM, no ad goes live. Store these parameters server-side at signup time, not just in analytics JavaScript that ad blockers strip out.
2. Server-side event capture
On your signup endpoint, persist the attribution data directly:
CREATE TABLE signups (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
utm_source VARCHAR(100),
utm_medium VARCHAR(100),
utm_campaign VARCHAR(100),
referrer TEXT,
channel VARCHAR(50) GENERATED ALWAYS AS (
CASE
WHEN utm_medium IN ('cpc','paid','ppc') THEN 'paid'
WHEN utm_source IS NOT NULL THEN 'organic_referral'
WHEN referrer ILIKE '%google%' THEN 'organic_search'
ELSE 'direct'
END
) STORED
);
3. Cohort-level CAC query
This is the query that stops you from overspending:
WITH monthly_signups AS (
SELECT
DATE_TRUNC('month', created_at) AS cohort_month,
channel,
COUNT(*) AS new_customers
FROM signups
GROUP BY 1, 2
),
monthly_spend AS (
SELECT month, channel, spend
FROM marketing_spend
)
SELECT
s.cohort_month,
s.channel,
s.new_customers,
COALESCE(m.spend, 0) AS spend,
CASE
WHEN s.new_customers > 0
THEN ROUND(COALESCE(m.spend, 0)::NUMERIC / s.new_customers, 2)
ELSE NULL
END AS cac
FROM monthly_signups s
LEFT JOIN monthly_spend m
ON s.cohort_month = m.month AND s.channel = m.channel
ORDER BY s.cohort_month DESC, s.channel;
Run this monthly. You’ll see exactly when paid CAC drifts above your LTV threshold while blended CAC still looks comfortable.
The decision framework
Use this before increasing paid spend:
| Condition | Action |
|---|---|
| Paid CAC < 1/3 x LTV | Scale paid spend aggressively |
| Paid CAC between 1/3 and 1/2 x LTV | Scale cautiously, optimize creatives |
| Paid CAC > 1/2 x LTV | Pause scaling, investigate channel efficiency |
| Organic ratio declining month-over-month | Invest in content/SEO before more paid |
The danger zone is when your organic ratio drops while you’re scaling paid. Your blended CAC stays flat but your true economics are deteriorating. This is how startups burn through runway while dashboards show green metrics. I’ve watched it happen in real time, and the worst part is everyone in the room feels good about the numbers right up until they don’t.
What to actually do with this
Track paid CAC separately from day one. Store UTM parameters server-side at signup time. A single channel column on your signups table gives you the foundation for every growth decision you’ll make.
Calculate your CAC distortion factor monthly. If paid CAC is more than 2x your blended CAC, your blended number is misleading you. Make paid CAC the metric you use for ad-spend decisions.
Monitor your organic ratio as a leading indicator. A declining organic ratio means your growth is increasingly dependent on paid channels. That’s the signal to invest in content, product-led growth, and referral mechanics, not to increase ad budgets.
The same discipline that lets a small team rationally evaluate self-hosting versus managed services applies directly to growth spending. Measure the real cost, not the comfortable average.
TAGS: startup, saas, productengineering, backend, api