Five channels, two business lines. The unusual part: leads bought a year after they arrived, so returns had to be measured across cohorts, not calendar years.
Product School sells product management certifications — B2C to individuals and B2B to enterprise training buyers — across five paid channels: Google, LinkedIn, Meta, Microsoft and Twitter. Average lifetime customer value is $4,199 per seat, and the sales motion runs through a call, so revenue lands weeks or months after the click that produced it.
I managed $3M+ in quarterly spend across the full paid account. This case study covers one business line within that — a $181K annual programme where I built the budget allocation and forecasting model from scratch. The scope is deliberately narrow because the interesting part isn't the size of the number, it's how the model handles revenue that arrives a year after the click.
That last detail is what makes the reporting hard. A lead generated in Q4 2020 can become revenue in Q2 2021. Any model that measures spend against same-period revenue will systematically misprice the channel.
Three failures were baked into conventional PPC reporting for this business:
Same-period ROAS understates a delayed-conversion business. Measuring 2021 spend against 2021 revenue ignores every seat sold this year to a lead acquired last year. The gap is not small — in the actual data, all-time ROAS was 623% against 480% for same-year. Report only the second number and paid media looks 30% weaker than it is.
Budget was tracked as a single pot. Without an allocation layer, there's no way to answer "how much of approved budget is actually live," "what's sitting unspent," or "what does B2B bottom-of-funnel cost us this month." Money gets approved and then goes untracked between approval and activation.
Forecasts built on your own past performance are optimistic by construction. A plan that assumes last year's CTR and CPL holds is a plan that assumes nothing gets more expensive. Auction costs rise. Setting a target off your own best numbers is how teams miss.
If the model chained every unit-economic step from spend to revenue, tracked budget through its full lifecycle from approval to activation, and forecast against external benchmarks rather than internal bests, the team could plan a year of spend with defensible numbers and know at any point in the month exactly where the money was.
Every metric connects to the next, so a change anywhere shows its downstream effect:
Spend → Impressions → CPM → CTR → CPC → Clicks → Click-to-Lead → CPL → Leads → Lead-to-Call → CPCall → Calls → Call-to-Sale → Seats Sold → LCV → Revenue → ROAS
Nine conversion steps, each with its own rate and cost. Change the assumed CPC and the model tells you how many seats you lose at the end of the chain, not just what clicks cost.
The model reports two revenue figures and two ROAS figures side by side for every channel and every quarter:
This is the part I'd point to first. It's the difference between measuring the channel and measuring the calendar.
| 2020 actuals | Same-year | All-time |
|---|---|---|
| Seats sold | 123 | 196 |
| Revenue | $516,391 | $670,652 |
| ROAS | 480% | 623% |
Rather than one forecast, the model runs three, and the plan is set on the most conservative:
| Scenario | Basis | Spend | Revenue | ROAS |
|---|---|---|---|---|
| Results 2020 | What actually happened | $107,572 | $516,391 | 480% |
| Forecast 2021 | Holding 2020 efficiency at higher spend | $180,960 | $865,782 | 478% |
| Goal 2021 | Using external industry benchmarks | $180,960 | $674,983 | 373% |
The goal scenario replaces internal metrics with published benchmarks — CTR 3.17%, CPC $3.20, click-to-lead 4.15% for search, and the corresponding figures for retargeting — each cited to source. The gap between the forecast and the goal, $865K against $675K, is the honesty margin. Planning to the lower number means the year is defensible if costs rise, and upside if they don't.
Rather than dividing the annual goal by four, quarterly targets were weighted using actual seat sales from 2018, 2019 and 2020:
| Quarter | Seats sold, 2018–2020 | Share |
|---|---|---|
| Q1 | 91 | 19.6% |
| Q2 | 112 | 24.1% |
| Q3 | 125 | 26.9% |
| Q4 | 137 | 29.5% |
Each quarter then carries its own spend, lead, call and revenue target derived from that share, so a Q1 miss against a flat target doesn't get read as a problem when Q1 is structurally the weakest quarter.
A three-level hierarchy tracking every dollar:
Business line (All PPC / B2C / B2B) → Channel (Google, LinkedIn, Meta, Microsoft, Twitter) → Funnel stage (TOFU / MOFU / BOFU) → Campaign
Each level tracks approved budget, budget currently active, budget pending activation, and remainder — plus daily spend, lifetime budget, days active, and start and end dates at campaign level. A separate "temporary strategies" pool holds short-run tests without polluting baseline allocation, with its own remainder line so the team can see what's committed versus what's genuinely free.
The paid goal was expressed as a share of the company-wide target rather than in isolation: 233 seats against a 2,500-seat company goal, a 9.32% share matching the previous year's contribution, with the in-year component set at 6.32% to improve on the prior 5.91%. Splitting the target 70/30 between current-year and prior-year lead cohorts made both halves of the funnel someone's explicit responsibility.
The model became the planning and reporting layer for the full paid programme: roughly $181K in annual budget across five channels and two business lines, with the largest single allocation being $28K/month across four Performance Max campaigns split by geography and funnel stage.
Its practical outputs:
Send me your site and what you're spending. I'll come back with what I'd fix first — free, no pitch.