MVP Factory
ai startup development

How to calculate true startup CAC with organic traffic

KW
Krystian Wiewiór · · 5 min read

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.

MetricFormulaExample ValueWhat it tells you
Blended CACTotal spend / all new customers$10.00Overall efficiency (misleading in isolation)
Paid CACPaid spend / paid-attributed customers$33.33True cost of buying a customer
Organic ratioOrganic customers / total customers70%How dependent you are on free channels
CAC distortion factorPaid CAC / Blended CAC3.3xHow 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:

ConditionAction
Paid CAC < 1/3 x LTVScale paid spend aggressively
Paid CAC between 1/3 and 1/2 x LTVScale cautiously, optimize creatives
Paid CAC > 1/2 x LTVPause scaling, investigate channel efficiency
Organic ratio declining month-over-monthInvest 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


Share: Twitter LinkedIn