For a fintech SaaS business, which marketing channels acquire customers most efficiently — not just by raw cost, but by how quickly that cost is recovered and how much lifetime value each channel's customers generate relative to what they cost to acquire? Where should marketing budget be prioritized, and where is spend at risk of destroying value rather than creating it?
A channel can look cheap on the surface (low cost per new customer) while actually being inefficient once you account for how long it takes to earn that cost back, or how little those customers are worth over time. Blending all channels into one average CAC can also hide this — a business needs channel-level detail to make good budget decisions.
CAC alone only answers "what did this customer cost?" — it doesn't say whether that cost was a good investment. Payback period converts CAC into a decision-relevant question: how many months until this customer has paid back what it cost to acquire them? This matters because a business has to fund that acquisition cost upfront, before any of it is recovered. LTV:CAC ratio goes a step further, asking whether the customer's entire expected lifetime value — not just their first few months — justifies the cost. Together, these three metrics turn a single cost figure into a genuine efficiency and risk assessment.
This project uses a simulated dataset of monthly marketing spend and new customer acquisition across 5 channels over 6 months, plus simulated per-customer revenue and churn behavior. Real acquisition spend and attribution data are commercially sensitive and not publicly available at a useful level of detail, so this project simulates a realistic scenario instead. Each channel was deliberately designed with different cost, volume, and customer-value characteristics — full design rationale is documented in the notebook. Data is generated entirely in-memory via Python; no external files or database are used.
Blended CAC across all channels was $147.52, but individual channel CAC ranged from $62.98 (SEO_Organic) to $217.17 (LinkedIn_Outbound) — a more than 3x spread. Reporting blended CAC alone hides this entirely.
| Channel | CAC | Payback (months) | LTV:CAC Ratio |
|---|---|---|---|
| SEO_Organic | $62.98 | 1.3 | 19.80 |
| LinkedIn_Outbound | $217.17 | 2.4 | 8.41 |
| Google_Paid | $149.73 | 2.7 | 6.10 |
| Meta_Ads | $138.41 | 3.1 | 4.00 |
| Affiliate | $127.00 | 3.2 | 3.52 |
LinkedIn_Outbound has the highest CAC by a wide margin, yet ranks second-best on both payback period and LTV:CAC ratio — higher revenue per customer and lower churn more than compensate for its expensive acquisition cost. A CAC-only view would incorrectly flag this as the weakest channel; it is actually one of the strongest.
Affiliate's CAC and payback period look similar to Meta_Ads on the surface, but its LTV:CAC ratio (3.52) is the lowest of all five channels — its higher churn rate erodes long-term value in a way payback period alone doesn't capture.
All 5 channels sit in either the "Low CAC, High LTV," "High CAC, High LTV," or "Low CAC, Low LTV" quadrants — notably, no channel falls into the "High CAC, Low LTV" danger zone.
A one-way ANOVA confirmed CAC differs significantly across channels (F = 37.64, p < 0.0001), despite each channel having only 6 monthly observations.
- Scale SEO_Organic, with a caveat. Lowest CAC and highest LTV:CAC ratio, but its efficiency was only tested at $800-$1,500/month spend — untested at higher scale, where diminishing returns likely apply.
- Continue investing in LinkedIn_Outbound despite its high CAC — its strong payback period and LTV:CAC ratio justify the cost.
- Re-evaluate Affiliate. Weakest LTV:CAC ratio, driven by highest churn. Investigate onboarding/retention improvements or reallocate spend toward SEO or LinkedIn.
- Never report blended CAC as the primary metric — it obscures a more than 3x spread between channels.
- Avoid over-concentrating budget in any single channel. Even strong performers carry channel-specific risk (SEO ranking changes, ad-platform pricing shifts). Diversification protects against this.
- Blending organic and paid traffic artificially lowers blended CAC.
- Ignoring churn when evaluating payback period alone can make a high-churn channel look healthier than it truly is.
- Treating CAC as static — this analysis assumes stable channel behavior going forward, which may not hold if market conditions change.
- Uses simulated, not real, marketing and acquisition data. Channel behaviors were deliberately designed to create testable patterns; real-world data would be messier.
- Predicted LTV uses a simplified formula (monthly revenue ÷ churn rate), not a full model accounting for seasonality or pricing changes.
- The statistical test is based on only 6 monthly observations per channel.
- Simulation (
src/simulate.py) — monthly spend and new customer counts generated per channel using a diminishing-returns formula (baseline + efficiency × √spend); individual customer revenue and churn simulated per channel's defined profile. - Metrics (
src/metrics.py) — blended CAC, channel-specific CAC, monthly CAC trend, payback period, and LTV:CAC ratio calculated using pandas. - Analysis & Visualization (
src/analysis.py) — all charts generated, plus a one-way ANOVA test confirming CAC differences across channels are statistically significant.
customer-acquisition-cost-analysis/ ├── notebooks/ │ └── 01_cac_analysis.ipynb # full narrated walkthrough ├── src/ │ ├── simulate.py # spend + customer simulation │ ├── metrics.py # CAC, payback, LTV:CAC calculations │ └── analysis.py # charts + statistical test └── outputs/ └── figures/ ├── channel_vs_blended_cac.png ├── cac_trend_over_time.png ├── cac_payback_period.png ├── ltv_cac_ratio.png └── cac_ltv_quadrant.png
# 1. Set up environment
python -m venv venv
source venv/Scripts/activate # Windows Git Bash
pip install -r requirements.txt
# 2. Run the full pipeline (simulation → metrics → charts → stats)
python src/simulate.py
python src/metrics.py
python src/analysis.pyAlternatively, open notebooks/01_cac_analysis.ipynb for a narrated,
cell-by-cell walkthrough with inline charts and explanations.
Python, pandas, NumPy, Matplotlib, Seaborn, SciPy
