Pipeline & forecasting
How I build a forecast leadership trusts: five inputs beyond coverage, a maturity ladder from weighted-score to ML, and a daily snapshot diff that catches drift on Tuesday instead of week 11.
Two quarters ago I signed off on a commit that came in 14% light, and the deals that killed us were the “Commit” deals nobody had touched in three weeks, not the ones anybody flagged. The forecast did not miss because the math was wrong. It missed because I was reading pipeline value and stage labels, and both of those are the last things to move. A deal goes quiet, the champion stops replying, the mutual plan stalls, and the stage stays exactly where it was until the day the rep finally slips the date. By then it is week 11 of a 13-week quarter and there is nothing left to do but explain it.
So I rebuilt how I forecast around one rule: the number is an output of inspection, not a replacement for it. What follows is the model I run now, the queries to stand it up, and the cadence that makes it hold. The teams that get this right land inside 5% variance quarter after quarter. The ones that do not are still reading pipeline value out loud on a 90-minute call and calling it a forecast.
Coverage tells you capacity, not this quarter
The first thing I stopped doing was treating 3x coverage as a forecast signal. Coverage decoupled from attainment somewhere around 2024, and for good reason. It answers “is there enough pipeline to theoretically hit,” which is a capacity-planning question, not “will we hit,” which is a this-quarter question. The right coverage number is not a flat 3x. It is 1 divided by your win rate. At a 50% win rate you need 2x. At 25% you need 4x. At 20% you need 5x. With win rates having fallen into the 19-21% band industry-wide (Ebsta/Pavilion 2025, down from roughly 29% a year earlier), a lot of teams still quoting 3x are quietly running at half the coverage they think they have.
Put your own numbers in and watch the ratio move. This is the read most rooms skip:
coverage
Below ~3x you are almost certainly going to miss unless win rates are unusually high. Above ~5x the number is either sandbagged pipeline or wishful staging. The healthy band is 3 to 4x.
coverage: 3.6x
I treat that ratio as a capacity gate at the start of a period, not a forecast. If it is thin in week 1, I can still source net-new pipeline that matures in time. If I only check it in week 10, all I can do is protect close dates on what already exists. The full weighting model, and why 3x lies, lives in the coverage ratio trap. Here the point is narrower: coverage sets the table, the five inputs below call the number.
The five inputs that actually predict
Weighted pipeline (deal amount times stage probability) is where most forecasts start and where too many stop. The problem is that a $500K deal at 20% forecasts identically to five $100K deals at 20%, and they behave nothing alike. I combine five inputs instead, and I weight them by what has predicted outcomes in my own closed-deal history, not by a vendor’s default.
Each input earns its slot for a reason:
- Stage-transition probability, built from a cohort of closed deals in the warehouse, not the pick-list probability someone typed into the CRM three years ago. The CRM number is a wish. The cohort number is what happened.
- Deal velocity versus baseline. A deal moving through stages slower than the segment median is slipping, whether or not the rep has admitted it. I compute days-in-stage against the median for that segment and flag anything past 1.5x.
- Engagement signals. Multi-thread depth and contact activity catch a slip 30 to 45 days before the close date moves. This is my earliest warning and the one I trust most. A single-threaded deal in a segment where multi-threading lifts win rate 130% (Ebsta/Pavilion) is a risk the stage label will not show you.
- Qualification completeness. I care more about a confirmed economic buyer and a documented decision process than about pain and metrics. Deals die on procurement and approval, not on whether the rep quantified the pain in the first call.
- Rep conviction, calibrated to history. A rep who calls Commit and lands 90% of them gets weighted differently from one who lands 55%. I score every rep’s commit accuracy and feed it back. Uncalibrated conviction is just optimism with a job title.
Here is what those inputs do to a real cohort. Sixty Commit deals at quarter start, tracked through each gate to close. The gap between what the room called Commit and what actually landed is the whole reason the model exists.
View as table
| Stage | Value |
|---|---|
| Commit deals at qtr start | 60 |
| Economic buyer confirmed | 60 |
| No velocity slip | 60 |
| Still engaged | 60 |
| Closed won in period | 60 |
The room forecast 60. The model forecast 27, and it was right by the second gate: 13 of those Commit deals had no confirmed economic buyer, which is a coin flip dressed as a commit. If you want the mechanics of catching those slips deal by deal, deal velocity and stage exit criteria is the companion build.
How maturity picks your combine method
You do not need a model. You need the right method for how much data you have, and jumping to ML early is a good way to ship a forecast trained on 40 deals that nobody can explain. The mistake I see most is a Series A team buying a forecasting engine that wants 5,000 closed deals to calibrate, feeding it 300, and then trusting a black box that is guessing.
| Where you are | What I'd use | |
|---|---|---|
| Under ~200 closed deals | Thin history, noisy stages | Weighted-score model. Simple, explainable, good enough to inspect against. |
| ~500 closed deals | Enough to build stage cohorts | Cohort-baseline transition probabilities. Roughly 80% of the value at 20% of the cost. |
| 5,000+ closed deals | Stable segments, clean stages | ML-assisted scoring on top of cohort baselines. Not before this. |
Most teams live at the middle rung and should stay there. Cohort-baseline is the workhorse: pull the last 500-plus closed deals, group them by the stage they touched, and compute what fraction eventually won. That is the query behind the whole model:
-- Entered-to-won conversion per stage, last 4 quarters.
-- Roll each opp's stage history up to the stages it touched,
-- then join to whether it eventually won.
WITH touched AS (
SELECT OpportunityId,
StageName AS stage_touched,
MIN(CreatedDate) AS entered_at
FROM OpportunityFieldHistory
WHERE Field = 'StageName'
AND CreatedDate = LAST_N_DAYS:365
GROUP BY OpportunityId, StageName
)
SELECT t.stage_touched,
COUNT(DISTINCT t.OpportunityId) AS entered,
COUNT(DISTINCT CASE WHEN o.IsWon THEN t.OpportunityId END) AS won,
ROUND(100.0 * COUNT(DISTINCT CASE WHEN o.IsWon THEN t.OpportunityId END)
/ COUNT(DISTINCT t.OpportunityId), 1) AS win_pct
FROM touched t
JOIN Opportunity o ON o.Id = t.OpportunityId
WHERE o.IsClosed = true
GROUP BY t.stage_touched
ORDER BY win_pct DESC
Store the output as custom metadata or a small object so every dashboard reads one source, not a hardcoded probability in ten places. When the motion shifts, you rebuild one table and the whole forecast re-weights.
Whatever method you run, define the forecast categories once and enforce them org-wide. Commit and Best Case only count if the close date lands in the period. A deal a rep loves with a close date in the next quarter is pipeline, not commit, no matter how much they want it in the roll-up. Here is the definition sheet I publish and hold reps to:
| Category | Definition (enforced) | Counts toward this-period forecast |
|---|---|---|
| Commit | EB confirmed, decision process documented, close date in period, rep would bet on it | Yes, at rep’s calibrated close rate |
| Best Case | Upside, close date in period, one gate still open | Partial, at stage weight |
| Pipeline | Qualified but close date out of period, or a gate unconfirmed | No |
| Omitted | No activity 21+ days, or no confirmed buyer | No, flagged for triage |
Cross-motion, the benchmarks that anchor those weights are worth keeping on the same page as the model:
| Metric | Value | Source |
|---|---|---|
| Win rate, overall | 19-21% (top performers 30%+) | Ebsta/Pavilion 2025 |
| Average sales cycle | 6.5 months (up from 4.9 in 2019) | Ebsta 2024 |
| Multi-threading win lift (over $50K) | +130%; 78% of deals still single-threaded | Ebsta/Pavilion 2025 |
| Reps missing quota, H1 2025 | 76% | Ebsta/Pavilion 2025 |
| Elite forecast variance | under 5% | revopsmasters 2026 |
The inspection cadence, and the diff that saves the quarter
The model is only as good as the cadence that feeds it. Here is the weekly run, in order, and the daily job underneath it.
- 1
1. Snapshot pipeline daily, diff it Tuesday
A daily Salesforce snapshot diffed against yesterday: amounts, stages, close dates, next-step dates. Drift shows up mid-week, not at quarter-end. This is the one job that pays for everything else.
- 2
2. Reps update before the call, not during
The roll-up is not data entry. If a rep is editing close dates live on the call, the call is theater. Fields are frozen at snapshot time.
- 3
3. Inspect Commit and Best Case against exit criteria
Observable criteria only: EB confirmed, next meeting on the calendar, decision process documented. Never "feels good." If inspection is vague, it becomes opinion instead of evidence.
- 4
4. Compute the five-input forecast, flag divergence
Where rep conviction and the signal model disagree by more than one deal-band, that deal gets a conversation. Agreement gets left alone.
- 5
5. Set the number as a range with a floor
A stated band. The floor is what I would bet my own money on. The commit is the floor, not the best case.
- 6
6. Score accuracy at close, per rep
Feed commit accuracy back into next quarter's conviction weighting. This is what makes input five real instead of decorative.
The daily snapshot is a few lines. Capture the open book each morning, then diff:
-- Daily snapshot: write one row per open opp per day.
SELECT Id, Name, OwnerId, StageName, Amount,
CloseDate, ForecastCategoryName, LastActivityDate,
NextStep
FROM Opportunity
WHERE IsClosed = false
-- The Tuesday diff: what moved since yesterday.
-- Pushed close dates and quiet Commit deals are the tells.
SELECT t.Id, t.Name, t.OwnerId,
y.CloseDate AS was_close, t.CloseDate AS now_close,
y.StageName AS was_stage, t.StageName AS now_stage,
t.Amount, t.LastActivityDate
FROM snapshot_today t
JOIN snapshot_yesterday y ON y.Id = t.Id
WHERE t.CloseDate <> y.CloseDate
OR t.StageName <> y.StageName
OR (t.ForecastCategoryName = 'Commit'
AND t.LastActivityDate < DATEADD('day', -21, CURRENT_DATE))
ORDER BY t.Amount DESC
Elite teams land inside 5% variance (revopsmasters 2026). I got there in the second full quarter after the rebuild, not the first, because rep conviction weighting needs a quarter of scored history before it means anything. The unlock was killing the 90-minute status meeting where reps read their pipeline out loud, and replacing it with a 30-minute exception-only call that only discusses deals the diff or the signals flagged. A better spreadsheet was never the answer.
If you do one thing this week, wire up the daily snapshot diff. Everything else compounds off catching drift on a Tuesday. The model tells you what a deal is worth; the diff tells you the day it started to slip, which is the only day you can still do something about it.
Keep reading
All guides →Territory & quota design
Audit the territory before you blame the rep: balance on opportunity, ramp-adjust capacity down to the number reps can actually produce, and set quota against real potential so the target is earnable.
RunCompensation design
Comp is the most expensive behavior tool a company owns. Pay mix by role, the quota-to-OTE red line at 6x, and the accelerator that quietly taught my best rep to sandbag.
RunOperating cadence
Three review tiers that never touch each other: weekly protects the forecast, monthly finds the pattern, quarterly plans the capacity. Here are the flags, the queries, and the build order.