You're spending money to acquire customers. But how long does it actually take to make that money back? CAC payback tells you exactly that—the number of months it takes for a customer's revenue to equal what you spent acquiring them. If you're not tracking this, you might be overspending on acquisition without realizing it.
Understanding CAC Payback
CAC payback is your acquisition cost divided by monthly revenue per customer. It's the heartbeat of unit economics.
Calculate Your Customer Acquisition Cost (CAC)
Total up all acquisition spend for a cohort—ads, tools, sales time—and divide by number of customers acquired. In Stripe, tag customers with Metadata fields to track acquisition channel and date, making it easier to segment payback by campaign.
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
// Retrieve customers acquired in a specific period
const customers = await stripe.customers.list({
limit: 100,
created: {
gte: Math.floor(new Date('2026-01-01').getTime() / 1000),
lte: Math.floor(new Date('2026-02-01').getTime() / 1000)
}
});
// Example: $5,000 spent, 50 customers = $100 CAC
const acquisitionCost = 5000;
const cac = acquisitionCost / customers.data.length;
console.log(`CAC: $${cac.toFixed(2)}`);
// Output: CAC: $100.00Measure Average Monthly Recurring Revenue (MRR) Per Customer
Fetch all active subscriptions using stripe.subscriptions.list() and calculate the total monthly revenue. Divide by active customer count to get average MRR per customer. This is the monthly revenue going toward payback.
// Get all active subscriptions
const subscriptions = await stripe.subscriptions.list({
status: 'active',
limit: 100
});
let totalMRR = 0;
let count = 0;
for (const sub of subscriptions.data) {
for (const item of sub.items.data) {
if (item.price.recurring?.interval === 'month') {
totalMRR += item.price.unit_amount / 100;
count++;
}
}
}
const avgMRRPerCustomer = totalMRR / count;
console.log(`Average MRR per customer: $${avgMRRPerCustomer.toFixed(2)}`);
// Output: Average MRR per customer: $150.00Calculate the Payback Period
Divide CAC by average MRR per customer. The result is months to payback. Less than 6 months is strong; under 12 months is typical for SaaS.
// Payback period = CAC / Average monthly revenue per customer
const paybackMonths = cac / avgMRRPerCustomer;
console.log(`CAC payback period: ${paybackMonths.toFixed(1)} months`);
// Example: $100 CAC ÷ $150 MRR = 0.67 months (≈ 3 weeks)
const examplePayback = 100 / 150;
console.log(`Healthy example: ${examplePayback.toFixed(2)} months`);
// Output: CAC payback period: 0.67 monthsacquisition_channel, acquisition_date, and campaign_id. This lets you segment and compare payback across different marketing sources.Tracking Payback Over Time and Across Campaigns
A single calculation tells you about one cohort. Tracking monthly shows whether your acquisition efficiency is improving.
Store Acquisition Metadata and Query by Campaign
When customers sign up, save acquisition details to their Metadata. Later, use stripe.customers.list() to filter by these fields and recalculate payback for each campaign. This reveals which channels deliver the fastest payback.
// Create customer with acquisition metadata
await stripe.customers.create({
email: '[email protected]',
metadata: {
acquisition_channel: 'google_ads',
acquisition_date: '2026-03-01',
campaign_id: 'spring_sale_2026'
}
});
// Later, retrieve and filter by campaign
const allCustomers = await stripe.customers.list({ limit: 100 });
const googleAdsCustomers = allCustomers.data.filter(
c => c.metadata?.acquisition_channel === 'google_ads'
);
console.log(`Google Ads customers: ${googleAdsCustomers.length}`);
// Output: Google Ads customers: 23Monitor Churn and Adjust Calculations
Listen to customer.subscription.deleted webhooks to detect churn. Early churn crushes payback—if a customer leaves after 2 months, they haven't generated enough revenue to justify acquisition spend. Recalculate payback monthly and track it over time.
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
// Handle subscription.deleted webhook
const handleStripeEvent = async (event) => {
if (event.type === 'customer.subscription.deleted') {
const subscription = event.data.object;
console.log(`Customer ${subscription.customer} churned.`);
// Recalculate payback for affected cohort
const monthsActive = (Date.now() - subscription.created * 1000) / (30 * 24 * 60 * 60 * 1000);
console.log(`Churned after ${monthsActive.toFixed(1)} months.`);
}
};
// Check if payback exceeds threshold
const paybackTarget = 6; // months
if (paybackMonths > paybackTarget) {
console.warn(`⚠️ Payback (${paybackMonths.toFixed(1)} mo) exceeds target (${paybackTarget} mo)`);
}
// Output: ⚠️ Payback (8.5 mo) exceeds target (6 mo)Common Pitfalls
- Underestimating acquisition costs. Ad spend is obvious, but add everything: tools, email platforms, sales salaries, landing page hosting. Incomplete CAC makes payback look artificially good.
- Ignoring payment processing fees. Stripe takes 2.9% + $0.30 per transaction. Use net MRR (after Stripe fees) in your payback calculation, not gross.
- Not accounting for churn. Payback assumes the customer stays forever. If 30% churn in the first 6 months, their payback never happens. Calculate separately for different cohorts.
- Mixing customers across different pricing plans without segmentation. Annual plans inflate MRR relative to monthly plans. Calculate payback separately per pricing tier for accuracy.
Wrapping Up
CAC payback is the lens that shows whether your customer acquisition is efficient or wasteful. By calculating it with Stripe data and tracking it monthly, you'll spot when acquisition costs are rising or MRR is falling—and you'll know it before the problem spirals. Monitor by cohort and campaign, and adjust spending accordingly. If you want to track this automatically across tools, Product Analyst can help.