TT Lab
Get started
Learn Learning paths Courses

Founding as a Developer — Validate Before You Build

Decide the Price Test and Channel Budget by Contribution Margin

Continue in TT Lab

Goal

Judge a pricing experiment by contribution margin, calculate churn, LTV, per-channel CAC, payback period, and LTV/CAC from the subscription records, and decide the price and the channel budgets with a rule set in advance.

Why it matters

If you set the price by conversion rate or revenue and pick channels by CAC alone, then the moment costs and churn attach, you end up in a structure where cash drains the more you grow. Unit economics is the calculation that puts the money each customer leaves and the money spent to bring that customer in on the same footing.

Materials

Definitions

Steps

  1. In /root/founder/pricing/arms.json, write conversion, refund_rate, and revenue_per_visitor (purchases × price ÷ visitors) for each price cell (A, B, C), and best_by_conversion.
  2. In /root/founder/pricing/unit.py, create contribution(price, costs) — costs is the dictionary read from costs.json, and the return value is the monthly contribution margin (a real number).
  3. In /root/founder/pricing/pervisitor.json, write contribution_per_visitor for each cell, plus best_by_contribution and best_by_revenue.
  4. In unit.py, add churn(fix, month, channel=None), and in /root/founder/pricing/churn.json, write monthly (each month from 2026-01 to 2026-06) and average.
  5. In /root/founder/pricing/ltv.json, write contribution (the monthly contribution margin at 14,900 won), avg_churn, ltv, and ltv_on_revenue (= 14900 ÷ average churn rate), computed as the common mistake.
  6. In /root/founder/pricing/cac.json, write by_channel (the five channels), blended (total ad spend ÷ total new customers), and paid_only (the ad spend of channels with spend > 0 ÷ the new customers of those channels).
  7. In /root/founder/pricing/channels.json, write for each channel churn (the average churn rate of only that channel's customers), ltv, payback_months, and ltv_cac (null if ad spend is 0).
  8. In /root/founder/pricing/decision.json, write price_arm (the cell with the largest contribution margin per visitor), scale (channels with ad spend > 0, LTV/CAC ≥ 3, and payback period ≤ 12, sorted), cheapest_cac_paid (among channels with ad spend > 0, the channel with the cheapest CAC), and cheapest_is_scalable (whether that channel is in scale).

Notes

Looking only at conversion rate

In /root/founder/pricing/arms.json, write conversion, refund_rate, and revenue_per_visitor for A, B, and C, and best_by_conversion.

conversion = purchases ÷ visitors, refund_rate = refunds ÷ purchases, revenue_per_visitor = purchases × price ÷ visitors.

The monthly contribution margin of one customer

In /root/founder/pricing/unit.py, create contribution(price, costs).

From the VAT-inclusive price get the supply value (× 100/110), get the fee by multiplying the inclusive price by the rate and adding the fixed amount. Then subtract the server and support costs.

Judge again by first-month contribution margin per visitor

In /root/founder/pricing/pervisitor.json, write contribution_per_visitor for each cell, plus best_by_contribution and best_by_revenue.

(purchases − refunds) × contribution(that price) ÷ visitors. Also check whether the winner by revenue and the winner by contribution margin are the same.

Monthly churn rate — the denominator is last month's payers

Add churn(fix, month, channel=None) to unit.py, and in /root/founder/pricing/churn.json write monthly (2026-01 to 2026-06) and average.

"Paid in M" means start ≤ M ≤ end (2026-06 if empty). The denominator is customers who paid in M−1, and the numerator is those of them who did not pay in M. The month before January is December of the previous year.

LTV — the numerator is contribution margin, not revenue

In /root/founder/pricing/ltv.json, write contribution, avg_churn, and ltv, plus ltv_on_revenue for comparison.

LTV = monthly contribution margin (at 14,900 won) ÷ average churn rate. For the comparison value, put 14,900 into the numerator as is. Remember that this model assumes constant churn and no discounting.

Channel CAC and blended CAC

In /root/founder/pricing/cac.json, write by_channel (the five channels), blended, and paid_only.

Ad spend is the sum over 2026-01 to 2026-06, and new customers are those whose start_month falls in the same period. The denominator of the blended CAC also includes organic inflow customers with 0 ad spend.

Churn, LTV, and payback period by channel

In /root/founder/pricing/channels.json, write churn, ltv, payback_months, and ltv_cac for each channel (ltv_cac is null if ad spend is 0).

For a channel's LTV, use the average churn rate calculated from only that channel's customers. Payback period = CAC ÷ monthly contribution margin.

Decide by the rule set in advance

In /root/founder/pricing/decision.json, write price_arm, scale, cheapest_cac_paid, and cheapest_is_scalable.

The rule is exactly what you set before calculating — ad spend > 0, LTV/CAC ≥ 3, payback period ≤ 12 months. Check separately whether the paid channel with the cheapest CAC passes the rule.