How I Built a Marketing Budget & ROI Advisor with Claude Code (And How You Can Too)

Your CAC is missing half the picture. The math, the CLAUDE.md, the AI system prompt, and the Claude Code sequence to build a Marketing Budget & ROI Advisor.

Sam Shev, Fractional CMO
Author
Sam Shev
Read Time
12 min read
Date
June 9, 2026
How I Built a Marketing Budget & ROI Advisor with Claude Code (And How You Can Too)

In my CMO dashboard post, I made the case that channel-based reporting is inherently flawed. Channel metrics are often vanity proxies: acquisition counts and click-through rates that look impressive but don't connect to revenue. They add noise, making it harder to distinguish genuine product fit from trial curiosity. And they have a weak statistical relationship to what actually matters: closed-won deals and retained MRR. The argument was that you need a fundamentally better measurement infrastructure, built on first-party data and full-funnel attribution.

I stand by that. But it raises an uncomfortable question: what do you do in the meantime?

Most teams can't overhaul their measurement infrastructure between now and next quarter's budget review. You still need to justify ad spend. You still need to defend channel investment to a CFO who wants to know what the return actually is. So I challenged myself: what happens if you take the most defensible version of channel metrics, ones that directly address the three charges I laid out, and see how far they can actually take you?

The Marketing Budget & ROI Advisor is my answer to that challenge. By layering cohort retention data on top of standard channel metrics, it ties every channel directly to the revenue and closed-won deals those customers generate over 12 months. That's a full-funnel view, not a snapshot at a single conversion point. It replaces vanity acquisition counts with LTV-grounded efficiency ratios, uses Month-3 retention to filter trial curiosity from genuine product fit, and connects channel spend to retained MRR, the kind of number a CFO actually cares about.

This post walks through how to build it yourself. We'll cover the three charges against channel metrics and how cohort analysis answers each one, the data model and metric definitions that power the tool, the CLAUDE.md project setup, the three-step calculation engine, the Netlify serverless function and AI system prompt, and the full Claude Code prompt sequence. The tool is free to use; this is how you build your own version.

The Case Against Channel Metrics

Before getting into the build, it's worth being precise about what's actually broken, because the fix only works if it targets the right problems.

Charge one: vanity. Most channel metrics measure activity, not outcome. CAC (Customer Acquisition Cost), what it costs on average to win a single new customer, tells you the price of the transaction. It says nothing about whether those customers stay, expand, or churn in sixty days. Click-through rates, MQL counts, cost per lead: these are snapshots at a single point in the funnel. They optimize for the moment of acquisition and stop there.

Charge two: noise. Channel metrics can't tell the difference between a customer who found genuine product fit and one who signed up out of curiosity and left three weeks later. Both show up as identical acquisitions in your reporting. Channels that generate low-friction signups (Paid Social optimized for conversion volume, for instance) actively select for the noisiest segment: price-sensitive, low-intent buyers who inflate your acquisition numbers and tank your retention curve.

Charge three: dependence. Channel metrics rarely have a statistically defensible relationship to closed revenue. A channel can produce thousands of leads with zero measurable effect on bookings. The number of steps between a channel metric and a closed-won deal is large enough that the causal chain breaks down. This is why marketing attribution debates never end: the data isn't connected to the outcome in a way that holds up to scrutiny.

Cohort analysis is what makes channel metrics answer these charges. It doesn't fix attribution entirely; nothing does, but it eliminates the vanity problem by grounding efficiency in retained revenue, it cuts through the noise by filtering on Month-3 retention behavior, and it narrows the dependence gap by tracing each channel's acquisition cohort all the way through to the revenue those customers actually generate.

Why Standard Channel Reporting Still Gets It Wrong

Even among teams that accept the case against vanity metrics, the most common response is to replace MQL count with CAC and call it a day. CAC is better than a lead count. It's also not enough.

CAC is still a snapshot. It measures what it costs to turn someone into a paying customer at a single point in time. It says nothing about what happens after that moment, and in a SaaS business, after that moment is where the money is made or lost.

B2B SaaS customer acquisition costs rose 14% in 2024, and the median company now spends $2.00 to acquire every $1.00 of new ARR. (Benchmarkit, 2025) With acquisition that expensive, the difference between a channel that retains at 80% and one that retains at 38% isn't a detail; it's the difference between building a business and subsidizing churn. CAC treats those two channels identically. This is charge one (vanity) and charge two (noise) compounding each other in real dollar terms.

The table below shows what that looks like. Paid Social ranks second by CAC. By LTV:CAC (the ratio of a customer's Lifetime Value, meaning total revenue generated before cancellation, to what it cost to acquire them), it sits last, because what looks like efficient acquisition is actually selecting for customers who churn fastest.

Channel Monthly Spend CAC Month-3 Retention Cohort LTV (12mo) LTV:CAC Ratio
Organic SEO $8,000 $95 74% $1,140 12.0x
Paid Search $22,000 $148 61% $820 5.5x
Paid Social $18,000 $112 38% $430 3.8x
Outbound ABM $22,000 $410 82% $2,050 5.0x
Direct & Referral $4,000 $68 79% $1,020 15.0x

A healthy LTV:CAC sits at 3:1 or higher, with top-performing B2B SaaS companies targeting 5:1. The industry median is 3.2:1. (Optifai, 2025) Most teams measure this as a blended company number. Per-channel LTV:CAC is where the noise gets filtered out and charge three: the dependence problem, which starts to get answered; you're now looking at a metric that connects channel spend directly to retained customer revenue.

There's a fourth failure mode that pure CAC misses: saturation. Scale any channel hard enough and you exhaust the highest-quality audience segments first, forcing every subsequent dollar to work harder for weaker results. The mechanics of how audience-level saturation compounds as you scale are worth understanding before building any budget model. One real-world MMM case study found that cutting a channel's budget by 20% produced only 1% less revenue; the channel was so saturated the last $50K was nearly inert. (Mass Analytics) Standard budget planners don't model this. The advisor does.

I call the framework powering this tool the Cohort-Value Attribution Framework: rank channels by the net present value of the cohort they produce, adjusted for where each channel sits on its efficiency curve, not by what it cost to acquire them.

The Data Model: Inputs Designed to Answer the Charges

The tool runs on five inputs per channel. Each one was chosen specifically because it addresses one or more of the three charges against channel metrics. Your marketing ops team should have all of these; if any require estimation, the AI memo will flag which assumptions are carrying the most weight in the recommendation.

Input Field Definition Source
Monthly Spend ($) Total dollars allocated to this channel in the measurement period Finance / ad platform exports
Customers Acquired New customers attributable to this channel in the same period CRM, closed-won by source
ARPU ($) Average monthly recurring revenue per customer from this channel Billing system, segmented by acquisition source
Month-3 Retention (%) Percentage of customers acquired through this channel still active at Month-3 Cohort report from your subscription analytics
CAC (calculated) Monthly Spend / Customers Acquired, computed automatically Derived from inputs above

Three of these inputs do specific work against the charges. Customers Acquired comes from CRM closed-won records, not lead counts; that's the anti-vanity input, because it counts the customers who actually converted, not the ones who downloaded a white paper. ARPU comes from the billing system segmented by acquisition source, which connects channel performance directly to real revenue, which starts to close the dependence gap. Month-3 retention is the anti-noise input: it filters out trial curiosity and surfaces genuine product fit, because channels that look identical at Month-1 often diverge sharply by Month-3 depending on the buyer intent they select for.

How to Calculate LTV:CAC Ratio, Cohort NPV, and Effective CAC by Channel

Before writing a line of code, document every metric definition in one place. This becomes your CLAUDE.md and your reference point whenever the model needs to make a judgment call. Here are the four formulas the advisor uses, and what each one answers.

Metric Formula What It Measures
Cohort LTV ARPU × Σ(r^t) for t = 1 to 12 12-month revenue from the average customer acquired through this channel, weighted by their observed retention curve
Effective CAC Base CAC × (1 + α × (x / x₀)) Projected acquisition cost at current spend level, adjusted upward for channel saturation
LTV:CAC Ratio Cohort LTV / Effective CAC Efficiency of the channel: how many dollars of lifetime value each dollar of acquisition cost generates
Cohort NPV Cohort LTV / (1 + d)^(T/12) - CAC Present value of the acquisition cohort after discounting for payback timeline and cost of capital


LTV:CAC directly answers charge one. Instead of measuring the cost of acquisition in isolation, it measures acquisition cost against the revenue those customers actually generate; the vanity problem dissolves because the metric is grounded in retained MRR, not lead volume. Cohort NPV goes further and starts to answer charge three: by discounting that LTV back to present value using the payback timeline, it produces a number that a CFO can evaluate as a capital allocation decision, not just a marketing metric. The dependence gap narrows because you're now connecting channel spend to a full-funnel revenue figure with time value built in.

Variable glossary:

  • r: Month-3 retention rate as a decimal (e.g., 0.82 for 82%), used as the monthly decay multiplier
  • t: month index from 1 to 12; the summation adds r^t for each month in the projection horizon
  • α (alpha): saturation coefficient controlling how steeply CAC escalates as spend scales; higher for audience-constrained digital channels, lower for capacity-constrained outbound
  • x: current monthly spend on this channel
  • x₀: baseline spend at which Base CAC was originally measured
  • d: discount rate, set at 10% to reflect cost of capital
  • T: CAC payback period in months; T/12 converts to years to match the annualized discount rate

Saturation coefficients (α) by channel type:

Channel α Value Rationale
Organic SEO 0.3 Content quality, not budget, is the ceiling
Paid Search 0.7 Query volume and auction competition cap growth quickly
Paid Social 0.8 Audience pool exhaustion at scale is fast
Outbound ABM 0.2 Constrained by sales capacity, not ad budget
Direct & Referral 0.1 Nearly zero; organic word-of-mouth, not spend-driven

The CLAUDE.md Project Setup

This is the file Claude reads at the start of every session. It encodes the challenge directly into the project: every metric definition, every constraint, and every UI standard is set up to answer the charges against channel metrics rather than reproduce them. Drop it in the root of your project directory before writing a single prompt.

# CLAUDE.md — Marketing Budget & ROI Advisor

## Project overview
Single-page browser tool for marketing budget optimization based on cohort LTV.Primary output is a budget reallocation recommendation grounded in Cohort NPV.All decisions prioritize mathematical correctness and executive-level clarity.
  
## Metric definitions (canonical — do not deviate)
  - ARPU: Average monthly recurring revenue per customer, channel-specific. Never blended.
  - CAC: Channel spend / customers acquired from that channel in the same period.
  - Cohort LTV: ARPU × Σ(r^t) for t = 1 to 12, where r = Month-3 retention rate as decimal.
  - Effective CAC(x): Base CAC × (1 + α × (x / x₀))
  - Cohort NPV: Cohort LTV / (1 + 0.10)^(T/12) 
  - CAC- LTV:CAC: Cohort LTV / Effective CAC. Flag any result below 3x in the UI.
  - Blended LTV:CAC: spend-weighted average of per-channel LTV:CAC ratios.
  - CAC Payback: CAC / (monthly ARPU × gross margin). Flag above 12 months.
  - Cohort NPV Improvement %: (recommended NPV - baseline NPV) / baseline NPV × 100

## Saturation coefficients (α) by channel
  - Organic SEO: 0.3
  - Paid Search: 0.7
  - Paid Social: 0.8
  - Outbound ABM: 0.2
  - Direct & Referral: 0.1
  
## Reallocation constraints
  - Maximum reallocation: 25% of total budget per optimization run.
  - Minimum channel floor: 10% of current allocation (no channel goes to zero).
  - Optimization target: maximize total Cohort NPV across the portfolio.
  - Discount rate (d): 10% annually.
  
## Naming conventions
  - Variables: camelCase in JS (channelSpend, cohortLtv, effectiveCac, cohortNpv)
  - Channel IDs: slugified lowercase (organic-seo, paid-search, paid-social, outbound-abm, direct-referral)
  - API: single Netlify function at [URL]
  
## UI standards
  - Input panel: left side, data grid, 5 channel rows
  - Output panel: right side, dual-axis Chart.js bar/line chart
  - KPI scorecard: Blended CAC Payback Period (months), Cohort NPV Improvement %, Blended LTV:CAC
  - AI memo: rendered markdown, exactly 3 paragraphs
  - Color coding: green (#1D9E75) LTV:CAC above 5x, amber (#BA7517) 3–5x, red (#D85A30) below 3x
  
## Tech stack
  - Frontend: HTML5, CSS3, vanilla JavaScript ES6+
  - Charts: Chart.js via CDN
  - Backend: Netlify Functions (serverless, free tier)
  - AI: Anthropic Claude Sonnet via API
  - No database, no auth, no infrastructure to maintain

The Three-Step Calculation Engine

Before anything reaches the AI, the tool runs three sequential calculations client-side. Each step is designed to answer one of the charges. This logic lives in calculations.js, which the Netlify function also imports so the math stays consistent on both ends.

Step 1: Cohort LTV (answering the vanity charge)

The analogy: think of two gym membership types. Type A costs $50 to sign up and members stay two months on average. Type B costs $80 and members stay nine months. The acquisition cost gap is obvious. The revenue gap over time is the number that actually drives your business. Standard channel reporting sees Type A as more efficient. Cohort LTV is how you prove it isn't.

Take the average monthly revenue per customer for a given channel (ARPU) and multiply it forward over 12 months using that channel's observed retention rate (r) as a monthly decay multiplier. The summation (Σ) adds r^t for each month from t=1 to t=12, giving you the total retention-weighted revenue the average customer from that channel generates. Paid Social retaining at 38% means r=0.38 and the curve falls fast. Outbound ABM retaining at 82% means r=0.82 and the curve holds. What looked like a vanity metric, acquisition cost is now connected to a revenue projection grounded in real retention behavior.

function calculateCohortLtv(arpu, retentionRate, months = 12) {
  // Cohort LTV = ARPU × Σ(r^t) for t = 1 to 12
  // r = Month-3 retention rate as monthly decay proxy
  // Summation accumulates retention-weighted revenue across the projection horizon
  let ltv = 0;
  for (let t = 1; t <= months; t++) {
    ltv += arpu * Math.pow(retentionRate, t);
  }
  return ltv;
}

Step 2: Effective CAC with Saturation (answering the noise charge)

The analogy: imagine the first five sales hires your team makes. Each one adds enormous incremental value. The fiftieth hire adds real but measurably smaller value because you're now competing for the same prospect pool. Marketing channels saturate the same way: your first dollar of Paid Search reaches the highest-intent searchers, and each dollar after that reaches someone a little less qualified at a slightly higher auction price. Standard CAC doesn't capture this degradation. Effective CAC does, and that degradation is one of the primary sources of noise in channel reporting.

Base CAC is the acquisition cost you measured at your original baseline spend level (x₀), the number sitting in your reporting right now. x is your current or proposed spend. The ratio x/x₀ tells you how far above baseline you're operating, and α (alpha) is a channel-specific saturation coefficient controlling how steeply costs escalate as that ratio grows. High-volume digital channels carry a higher α. Relationship-driven channels like Outbound ABM carry a lower one because the constraint there is sales capacity, not audience supply. The output, Effective CAC(x), is what acquisition actually costs at current spend, always higher than Base CAC once you cross baseline. The gap between the two is exactly the noise that standard reporting ignores.

const SATURATION_ALPHA = {
  'organic-seo': 0.3,
  'paid-search': 0.7,
  'paid-social': 0.8,
  'outbound-abm': 0.2,
  'direct-referral': 0.1
};

function calculateEffectiveCac(baseCac, currentSpend, baselineSpend, channelId) {
  // Effective CAC(x) = Base CAC × (1 + α × (x / x₀))
  // α is the channel-specific saturation coefficient
  // x/x₀ is how far above baseline the current spend sits
  const alpha = SATURATION_ALPHA[channelId] || 0.5;
  const spendRatio = currentSpend / baselineSpend;
  return baseCac * (1 + alpha * spendRatio);
}

Step 3: Cohort NPV (answering the dependence charge)

The analogy: if someone offered you $10,000 today or $12,000 two years from now, the $12,000 is worth less than face value because you're giving up what the $10,000 could have earned in the meantime. This is the same problem channel reporting has with the dependence charge: even when you can trace a channel to closed-won deals, the timing of that revenue matters for a company managing runway. Cohort NPV closes the dependence gap by expressing the full-funnel revenue contribution of each channel as a present-value figure, the kind of number a CFO can evaluate as a capital allocation decision, not a marketing dashboard metric.

Take the Cohort LTV from Step 1 and divide it by a compound discount factor. d is the discount rate (10% annually), T is the average CAC payback period in months, and T/12 converts that figure into years to match the annualized rate. The larger T is, the bigger the denominator, and the lower the present value. Subtract CAC (Customer Acquisition Cost for this channel) and what remains is the net present value of the acquisition cohort: the full-funnel revenue contribution of that channel expressed in today's dollars. Median gross profit payback for B2B SaaS sits at around 23 months. (KeyBanc, 2024) Cohort NPV builds that timeline directly into the optimization target.

function calculateCohortNpv(cohortLtv, cac, paybackMonths, discountRate = 0.10) {
  // Cohort NPV = Cohort LTV / (1 + d)^(T/12) - CAC
  // T/12 converts payback period from months to years to match annualized discount rate
  // The larger T is, the heavier the discount — channels with long payback periods
  // lose present value even when their gross LTV looks strong
  const discountFactor = Math.pow(1 + discountRate, paybackMonths / 12);
  return (cohortLtv / discountFactor) - cac;
}

The Netlify Function and AI System Prompt

The serverless function lives at /.netlify/functions/optimize-budget. It takes the channel payload from the client, runs the three calculations above on each channel, then passes the enriched data to Claude Sonnet. The system prompt is written to accept the challenge explicitly; the AI reasons about full-funnel cohort behavior, not snapshot acquisition metrics. The response comes back as a JSON object with the recommended budget array and the executive memo.

The full system prompt:

You are an expert B2B SaaS Fractional CMO and unit economics modeler.

The user has provided multi-channel marketing data including spend, customers acquired,
ARPU, and Month-3 retention rates per channel. Pre-calculated values for Cohort LTV,
Effective CAC, LTV:CAC, and Cohort NPV are included in the payload.

Return a single valid JSON object with exactly two keys:
1. "budgetAllocation": array of objects, one per channel:
   { channelName, currentSpend, recommendedSpend }
2. "executiveMemo": string, exactly 3 paragraphs in markdown

Follow this analytical sequence:

STEP 1 — Evaluate unit economics per channel:
- Identify channels with LTV:CAC below 3x as reallocation candidates.
- Identify channels where Effective CAC is growing faster than Cohort LTV as saturating.
- Protect channels with payback periods under 6 months regardless of LTV:CAC.

STEP 2 — Generate the reallocation:
- Shift no more than 25% of total budget in aggregate across all channels.
- No channel drops below 10% of its current allocation.
- Maximize total portfolio Cohort NPV, not average LTV:CAC.
- Consider both efficiency (LTV:CAC) and scale (customers per month) — a 15x channel
  producing 30 customers serves a different objective than a 5x channel producing 500.

STEP 3 — Write the executive memo:
- Paragraph 1: What the data shows — which channels produce LTV-efficient cohorts,
  which are saturating, and what the current blended LTV:CAC implies about portfolio health.
- Paragraph 2: What you are recommending and why — the specific reallocation logic
  and the trade-offs between volume, efficiency, and payback speed.
- Paragraph 3: Operational guardrails — what needs to change in creative, targeting,
  or sales coordination to realize the projected improvement.

When a key assumption (ARPU, retention rate) appears to be an estimate rather than
a verified actual, note this in the memo and qualify the confidence level accordingly.

Return only valid JSON. No markdown code fences, no preamble, no explanation outside
the JSON object itself.


The Netlify function wrapper:

// netlify/functions/optimize-budget.js
const Anthropic = require('@anthropic-ai/sdk');

exports.handler = async (event) => {
  const { channels } = JSON.parse(event.body);

  // Run the three-step calculation engine on each channel
  const enrichedChannels = channels.map(ch => ({
    ...ch,
    cohortLtv: calculateCohortLtv(ch.arpu, ch.retentionRate),
    effectiveCac: calculateEffectiveCac(ch.cac, ch.spend, ch.baselineSpend, ch.id),
    ltv_cac: calculateCohortLtv(ch.arpu, ch.retentionRate) / ch.cac,
    cohortNpv: calculateCohortNpv(
      calculateCohortLtv(ch.arpu, ch.retentionRate),
      ch.cac,
      ch.paybackMonths
    )
  }));

  const client = new Anthropic();
  const response = await client.messages.create({
    model: 'claude-sonnet-4-20250514',
    max_tokens: 1000,
    system: SYSTEM_PROMPT, // the prompt above
    messages: [{
      role: 'user',
      content: JSON.stringify(enrichedChannels)
    }]
  });

  const result = JSON.parse(response.content[0].text);

  return {
    statusCode: 200,
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(result)
  };
};

How to Build a Marketing Budget Optimizer with Claude Code: The Full Prompt Sequence

Start with the CLAUDE.md file in your project root and run these seven prompts in order in Claude Code. Each one builds on the last. The whole build took me an afternoon for the initial version and another day to tune the prompt engineering and chart logic.

Prompt 1: Scaffold the application:"Create a single-page HTML5 application for a marketing budget and ROI advisor. The layout has three panels: a left input panel with a data grid for five channels (Organic SEO, Paid Search, Paid Social, Outbound ABM, Direct & Referral), each row accepting Monthly Spend, Customers Acquired, ARPU, and Month-3 Retention %; a right output panel with a Chart.js dual-axis bar/line chart placeholder; and a bottom panel for an AI-generated executive memo. Add an Optimize Budget button that will eventually trigger the serverless function. Use the color system from CLAUDE.md. No placeholder data yet, empty state only."

Prompt 2: Build the calculation engine:"Create a calculations.js helper file. Implement the three functions defined in CLAUDE.md: calculateCohortLtv using the ARPU × Σ(r^t) formula for t = 1 to 12, calculateEffectiveCac using the Hill-style saturation formula with the channel-specific α values from CLAUDE.md, and calculateCohortNpv using the discount rate formula. Add JSDoc comments to every function documenting each parameter, its type, and its business meaning. Export all three functions for use by both the frontend and the Netlify function."

Prompt 3: Build the Netlify serverless function:"Create a Netlify function at netlify/functions/optimize-budget.js. It should accept a POST request with a JSON body containing a channels array. Import the three calculation functions from calculations.js, run all three on each channel, then send the enriched payload to the Anthropic Claude API using the system prompt defined in CLAUDE.md. Parse the returned JSON and pass it back to the client as the function's response. Handle errors from the Anthropic API gracefully and return a 500 with a message string if the AI call fails."

Prompt 4: Connect the UI to the API:"Wire the Optimize Budget button to the Netlify function. On click, compile the input grid values into a channels JSON array, POST it to /.netlify/functions/optimize-budget, and handle the response. On success, store the returned budgetAllocation and executiveMemo in component state. On error, display a user-facing error message in the memo panel. Add a loading state to the button while the request is in flight."

Prompt 5: Build the Chart.js visualizations:"Replace the Chart.js placeholder with a working dual-axis chart. The primary Y-axis (bar chart) should show Current Spend vs Recommended Spend per channel. The secondary Y-axis (line chart) should show Cohort LTV per channel. Use a destroy-and-redraw pattern before each new render to prevent stale dataset artifacts. Label both axes clearly. Use the color system from CLAUDE.md: green above 5x LTV:CAC, amber 3–5x, red below 3x."

Prompt 6: Build the KPI scorecard:"Add a KPI scorecard row between the chart and the memo panel. It should display three metrics: Blended CAC Payback Period in months (spend-weighted average across channels), Cohort NPV Improvement % (recommended minus baseline, divided by baseline), and Blended LTV:CAC (spend-weighted average). Each KPI card should show the current value and the projected value after reallocation side by side. Color-code using the thresholds in CLAUDE.md."

Prompt 7: Refine for executive readability:"Audit the full UI for executive clarity. The memo panel should render the three-paragraph markdown response with proper heading and paragraph spacing. The input grid should validate that retention rates are between 0 and 1 and that spend values are positive before enabling the Optimize button. Add a Reset button that clears the output state without clearing the input grid. Ensure the layout is responsive and stacks to a single column on screens narrower than 768px."

What the Output Actually Proves

After a real optimization run, the executive memo reads something like this:

Current portfolio analysis: The channel mix carries a blended LTV:CAC of 4.2x, which sits above the 3x threshold but masks meaningful divergence underneath it. Paid Social is generating customers at a 3.8x LTV:CAC, barely above the minimum, while carrying $18,000 of monthly spend. Direct & Referral and Organic SEO, at 15x and 12x respectively, are the two most capital-efficient channels in the mix and are currently underfunded relative to what their efficiency headroom supports.
Recommended reallocation: I'm shifting $4,500 from Paid Social and redistributing it across Organic SEO (+$2,800) and Direct & Referral (+$1,700). Paid Social's Month-3 retention of 38% is the primary driver; the cohort it produces retires value too quickly to justify its current spend share at scale. Outbound ABM stays at $14,000 despite its 5.0x LTV:CAC because its 82% Month-3 retention makes its NPV the strongest in the portfolio at a 14-month payback; cutting it to fund faster-payback channels would trade long-term portfolio value for short-term cash recovery speed.
Operational guardrails: Reallocating into Organic SEO requires a 60-to-90-day content production runway before volume materializes; this is a Q2 reallocation that pays off in Q3. The Direct & Referral increase works only if the referral program has structured incentives; organic word-of-mouth doesn't scale with budget. Review Paid Social creative cadence before cutting spend; the retention gap may reflect audience fatigue rather than a structural channel quality problem, in which case creative refresh is a lower-cost diagnostic than budget reduction.

Read that memo against the three charges. The recommendation doesn't reference MQL counts or click-through rates; it references retained revenue, cohort NPV, and payback timelines. That's the vanity charge answered. It identifies Paid Social's 38% Month-3 retention as the primary signal driving the reallocation, not its raw acquisition volume; that's the noise charge answered. And it connects the budget decision directly to a full-funnel revenue outcome, with the KPI scorecard showing Blended LTV:CAC moving from 4.2x to 5.1x and Cohort NPV improving 18%; that's the dependence gap narrowing.

The tool doesn't eliminate the fundamental attribution problem. No tool does. But it makes channel metrics do something they rarely do in practice: earn their place in a revenue conversation.

How to Connect Real Data to the Marketing Budget & ROI Advisor

The tool runs on sample data out of the box, but the architecture is identical to what you'd use with live sources. What makes Claude Code well-suited for this step is MCP, the Model Context Protocol, an open standard that lets Claude connect directly to external tools and platforms rather than working through manual exports or intermediary files. In practice, that means Claude Code can query your CRM, pull spend data from your ad platforms, and read retention cohorts from your billing system in a single session, without you stitching the connections together manually.

The connection sequence matters here more than it might with a general dashboard, because the five inputs this tool needs come from fundamentally different systems with different data quality levels. Getting the order wrong means you're validating downstream metrics against upstream data you haven't confirmed yet.

Start with ad spend and CRM closed-won: these are your two most reliable anchors. Google Ads, LinkedIn Campaign Manager, and Meta Ads Manager all expose campaign-level spend data through well-documented APIs that Claude Code can connect to through MCP, pulling monthly spend at the channel level directly into the input grid. For Customers Acquired, HubSpot and Salesforce both support MCP-compatible API connections that let Claude Code query closed-won opportunities by original lead source, which is the right denominator, not lead count or MQL count. Getting these two sources connected first lets you validate the CAC calculation against a number your finance team already tracks, which gives every downstream metric a credible foundation.

Second pass: billing system for ARPU. Stripe, Recurly, and Chargebee all provide MRR and subscription data at the customer level. The key field you need is average monthly recurring revenue segmented by acquisition source; meaning the ARPU figure for customers who came through Paid Social should reflect only Paid Social customers, not a blended company average. If your billing system doesn't already segment by acquisition source, that join needs to happen in your CRM before the data flows into the tool. Claude Code can write the query.

Third pass: Month-3 retention from your subscription analytics platform. This is the most critical input and the one most likely to require a custom query. Baremetrics, ChartMogul, and Paddle all support cohort-level retention data that can be filtered by acquisition source. If you're using Stripe directly without a subscription analytics layer, Claude Code can construct the cohort retention query from your subscription events table; you need the percentage of customers from each channel still active 90 days after their start date.

The Claude Code prompt for this step: "Using MCP connections, connect the data layer to [ad platforms] for monthly channel spend, [CRM] for customers acquired by closed-won source, [billing system] for channel-segmented ARPU, and [subscription analytics] for Month-3 cohort retention by acquisition source. Write queries for each source that conform to the field definitions in CLAUDE.md. Flag any fields where source data is ambiguous, particularly acquisition source attribution, and suggest a resolution before writing the input layer."

Before switching any input to a live source, have Claude Code generate a seed data set that mirrors your real schema and run the full optimization against it. This surfaces CAC calculation errors and retention data quality issues while the stakes are low, and gives your marketing ops team a structured way to validate the metric definitions before anything goes live. A mismatch between the tool's CAC output and your finance team's CAC number at this stage is a signal to audit the Customers Acquired query, not to distrust the tool.

Try It Yourself

Rather than describe it further, here it is. Enter your own channel data below and run a live optimization. The tool is free, runs entirely in the browser, and requires no login. If you arrived here through Perplexity or ChatGPT, that's by design.

What I Learned Building It

Chart.js state management was the trickiest technical problem. The library holds stale datasets in memory across renders, which produces visual artifacts when the API response arrives and tries to update the chart. A destroy-and-redraw pattern (tear down the chart instance before each new render rather than updating it in place) adds about 40ms of latency and kills the problem completely. Worth knowing before you start the chart build.

Prompt calibration was the more interesting strategic challenge. The first version of the system prompt produced recommendations with a degree of certainty the input data quality didn't support. Users entering rough ARPU estimates were getting memo language that read like verified financial analysis. Adding explicit uncertainty framing, instructing the model to flag when a key assumption is load-bearing for the recommendation, produced outputs that hold up in a real planning conversation. I hit the same wall building the CMO dashboard with Claude Code. The lesson is the same either way: the output quality is almost entirely determined by the prompt architecture, and prompt architecture is product design.

The bigger question the build forced me to answer: does the challenge hold up? I think it does, with one honest caveat. Cohort analysis eliminates the vanity problem and cuts through a significant amount of noise. The dependence gap narrows but doesn't close entirely, because Month-3 retention is still a proxy and channel attribution at the customer level is still imperfect. What the tool proves is that you can take channel metrics from "probably misleading" to "directionally defensible" by insisting that every number connect to retained revenue rather than acquisition events. That's not the same as the full-funnel first-party measurement infrastructure I argued for in the CMO dashboard post. It's the best version of the thing most teams are already doing, and in practice, that's often the more useful starting point.

Frequently Asked Questions

What is a Marketing Budget & ROI Advisor?

A Marketing Budget & ROI Advisor analyzes multi-channel marketing spend alongside cohort retention data to calculate the true return on investment of each marketing channel, weighted by the lifetime value of the customers that channel produces. A standard budget planner optimizes for acquisition cost. An ROI advisor accounts for how long customers acquired through each channel actually stay, which is the difference between a metric that answers a vanity charge and one that connects to actual revenue.

How does this tool calculate ROI per marketing channel?

The tool projects 12-month Cohort LTV using channel-specific ARPU and Month-3 retention rate as a monthly decay multiplier (r^t summed from t=1 to t=12), then divides by Effective CAC, the acquisition cost adjusted upward for where the channel sits on its saturation curve. The result is a channel-specific LTV:CAC ratio that reflects both the quality of the customers a channel produces and the true cost of acquiring them at current spend levels.

What is diminishing returns modeling in marketing budget optimization?

Diminishing returns modeling uses a response function (in this tool, a Hill-style saturation curve) to simulate how the effective cost of acquiring a customer through a given channel increases as spend scales. Your first dollar of Paid Search spend reaches the highest-intent searchers; each subsequent dollar reaches a progressively less qualified audience at a progressively higher auction price. This is one of the primary sources of noise in channel reporting: CAC measured at baseline spend is meaningfully different from CAC at 2x baseline spend, and most budget models don't account for that gap. (Analytical Alley)

How should SaaS companies use cohort retention data in budget decisions?

Map each marketing channel's acquisition cohort to its own retention profile, rather than applying a company-wide average churn rate uniformly. Different channels select for different buyer segments, and the retention gap between channels is exactly where the noise charge against channel metrics lives. A channel producing customers retaining at 80% at Month-3 and one producing customers retaining at 40% look identical in standard channel reporting. Cohort analysis is what separates them.

What is a good LTV:CAC ratio for a B2B SaaS company?

A healthy LTV:CAC ratio for B2B SaaS is 3:1 or higher. The industry median sits at 3.2:1. (Optifai, 2025) Ratios above 5:1 indicate strong unit economics with headroom to invest more aggressively in growth. Ratios below 3:1 signal that acquisition costs are too high, retention is too low, or both, making cohort-level analysis by channel the right first diagnostic before any reallocation decision.

What is the difference between CAC payback period and LTV:CAC ratio?

CAC payback period measures time: how many months of retained revenue it takes to recover what you spent to acquire a customer. LTV:CAC measures value: how many dollars of lifetime revenue each dollar of acquisition cost generates over a defined horizon. A channel can have a short payback period and a poor LTV:CAC ratio if retention drops off sharply after the payback month, or a long payback period and a strong LTV:CAC if the customer retains for years after cost recovery. The Cohort NPV calculation in this tool accounts for both by discounting future LTV against the payback timeline, which is why it's a better answer to the dependence charge than either metric alone.

How do you model diminishing returns in a marketing budget?

Use a saturation response function that maps channel spend to effective acquisition cost. The most common approaches are the Hill function (used in this tool), the Adstock model, and the S-curve. All three work the same way: as spend increases beyond the baseline level where your CAC was originally measured, the model applies an escalating cost multiplier reflecting audience exhaustion, auction competition, and creative fatigue. The channel-specific alpha (α) coefficient controls how steeply that multiplier grows, which is why high-volume digital channels like Paid Social get a higher α than relationship-driven channels like Outbound ABM. For a deeper look at how diminishing returns behave at the channel level as you scale, go deeper there.

Sam Shev

Written by Sam Shev

Sam Shev is a Fractional CMO specializing in early-stage SaaS and AI-native startups, with marketing leadership experience at Bloxley, Ava Protocol, Lightbits Labs, and iManage. He writes about the intersection of marketing strategy and technical reality at samshev.com and on Medium.