GTM Operations
A Third of Your Pipeline Is Already Dead. Your Coverage Number Counts It Anyway.
Coverage math counts every open dollar as live. Roughly 30% of it has had no activity in 21 days and is never closing (Ebsta/Clari). Here is the strip that turns raw pipeline into the live-and-weighted number, and the three queries that build it.
· 12 min read
Coverage math has one rule everyone runs on: every open dollar counts. A deal is open, it has an amount, it sits in a stage, so it goes into the pipe and into the coverage ratio and into the forecast. That rule is wrong, and it is wrong by about a third. Roughly 30% of open pipeline has had no activity, no email, no call, no meeting, no note, in 21 days or more (Ebsta and Clari). It sits green in the forecast and it is dead. It has been dead for weeks. The rep has not touched it because they already know, somewhere they will not say out loud, that it is not closing. But nobody made them mark it, so it lives on as a number that makes the pipeline look healthier than it is.
These are zombie deals, and they do the most damage in coverage math. A rep with 4x coverage and 30% zombies has 2.8x of live coverage and a forecast built on the difference (Clari). Count the dead dollars and you walk into a board meeting carrying a miss you have not booked yet. The autopsy is a query. You do not need judgment to find the bodies, you need a filter, and the filter is stage plus close date plus last activity.
Watch it happen to a real pipe. Start with $10M of raw open pipeline, every dollar counted, 4x coverage against a $2.5M quarter. Then strip the zombies. Then weight what survives by how its stage closes in your history. The field of dots is your raw pipeline; each stage dissolves the dollars that were never going to convert.
That collapse from 4x to roughly 1x is the framework in one image. The middle stage is the whole point of this piece: the zombie strip, a no-activity-21-days filter that turns raw pipeline into live pipeline before anyone weights or forecasts it. Below is how to build it, keep it built, and locate your own team on it. Most teams have never run the strip once, which means their coverage number is the leftmost dot in that field, and they are managing to it.
The three shapes of zombie
Before the query, know what you are looking for. Zombies come in three shapes and each has a different SOQL signature.
The stalled deal: open, in an active stage, no activity in 21+ days. It stopped moving and nobody killed it. This is the largest set, and it is the middle stage of the dissolve above.
The past-due deal: open with a CloseDate already in the past. It was going to close last month, it didn’t, and the rep keeps sliding the mental date without sliding the field, or worse, the field is still last month and everyone ignores it.
The immortal deal: open for longer than twice your median sales cycle. B2B cycles now average 6.5 months, up from 4.9 in 2019 (Ebsta 2024), so if your team closes in 60 days and this has been open 140, it is not a deal, it is a habit.
The three shapes are not mutually exclusive, but they need three different filters. Here is how they map:
The query
Start with the stalled set, because it is the biggest and the cleanest. Any open opportunity whose most recent activity is older than 21 days:
SELECT Id, Name, Owner.Name, StageName, Amount, CloseDate, LastActivityDate
FROM Opportunity
WHERE IsClosed = false
AND (LastActivityDate < LAST_N_DAYS:21 OR LastActivityDate = null)
ORDER BY Amount DESC
The LastActivityDate = null clause matters more than the date clause. A null there means the opportunity has never had a logged task or event tied to it at all. Those are not stalled, they were never started, and they are the purest zombies in the pile.
Now the past-due set:
SELECT Id, Name, Owner.Name, StageName, Amount, CloseDate
FROM Opportunity
WHERE IsClosed = false
AND CloseDate < TODAY
ORDER BY CloseDate ASC
Every row here is a deal that promised to close and didn’t, still sitting open with a date in the rear-view. Sort ascending and the oldest broken promises float to the top.
The immortal set needs your median cycle. Get it, then filter on age since creation:
SELECT Id, Name, Owner.Name, StageName, Amount, CreatedDate
FROM Opportunity
WHERE IsClosed = false
AND CreatedDate < LAST_N_DAYS:120
ORDER BY CreatedDate ASC
Swap 120 for twice your real median. These are the deals that have outlived the natural lifespan of a deal on your team.
A note on the union before you run all three. A single deal can be all three shapes at once: stalled, past-due, and immortal. If you report the three sets separately you triple-count it and the total looks worse than the live pipe is, which undercuts your credibility the moment a rep spots their one deal in three tabs. Union the three query results on Id so each dead deal appears exactly once, then tag it with which shapes it matched. A deal that trips all three filters is the most dead thing in your pipeline and belongs at the very top of the list, but it is still one deal, and the number you carry into the forecast conversation has to be honest about that.
One more filter to layer in once the basics work: exclude deals below a dollar floor from the rep conversation. A $2K deal with no activity is not worth a rep’s one-on-one minute, and cluttering the list with them trains reps to ignore the whole report. Set a threshold, work the dead deals that move coverage, and let a bulk hygiene rule sweep the small stuff quarterly.
Why the pipeline is full of them
Zombies are the downstream symptom of leaks upstream, and on the funnels I have traced the upstream numbers are grim. About 47% of MQLs never clear sales acceptance, and better than four in ten raw leads are never contacted at all. So a large fraction of what enters the top was never real, and some of it gets converted into opportunities anyway by a rep hitting quota on activity metrics rather than intent. That junk becomes the immortal deals, the ones that never had a logged activity because there was never anyone real on the other end to have an activity with.
The funnel below is where the zombies are born. Watch how much of the top never survives to a real conversation, and notice the drop lands at the very top where nobody is looking, not at the bottom.
View as table
| Item | Value |
|---|---|
| Raw leads | 1,000 |
| Contacted | 560 |
| MQL | 300 |
| Sales accepted | 159 |
| Opportunity | 96 |
The stalled deals are different. Those were real once and died quietly, and the rep left them open because an open pipeline is a safer place to hide than a closed-lost report the manager reads. This is the incentive that keeps the graveyard full: a deal marked closed-lost is a visible loss the rep has to explain, while a deal left open in a late stage is a number that flatters the rep’s pipeline and buys another month of silence. Until you change what is safer, the pile rebuilds no matter how many times you clean it.
That is why the null-activity case deserves separate treatment from the stalled case. A stalled deal had a human on the other end who went quiet, and it might revive with a well-timed touch. A null-activity deal never had a logged interaction at all, which means either it was a bad conversion the rep created to hit an activity number, or the buyer was never real. Those do not revive, because there is no relationship to reawaken. When you hand a rep their list, sort the null-activity deals to the top and treat them as the first close-losts, because they are the cheapest to kill and the least likely to cost you anything real.
The worked strip
The point of the strip is the forecast, not tidiness. Run the two cuts on the $10M pipe from the dissolve above and the numbers reconcile. Strip 30% for no activity in 21 days and $7M survives, which is the 2.8x middle stage. Then weight the survivors by stage close rate and about $2.6M is real forecast, which is the 1.05x you saw the field collapse to. Here is that reconciliation as a table, so the two stages of the strip are explicit:
| Stage of the strip | Pipeline | Coverage vs $2.5M | What it counts |
|---|---|---|---|
| Raw open | $10.0M | 4.0x | Every open dollar, dead or alive |
| After zombie strip | $7.0M | 2.8x | Only deals with activity in 21 days |
| Live and weighted | $2.6M | 1.05x | Survivors weighted by stage close rate |
Put the reported number next to the live number and the gap is the size of the surprise. A team walking in at 4x is walking in at 1.05x and does not know it.
| What the forecast shows | What is live once you look | |
|---|---|---|
| Open pipeline | $10M, all green | $7M live, $3M dead |
| Coverage | 4.0x, "we are covered" | 2.8x once zombies come out, 1.05x weighted |
| Largest deal | Counted at full amount | Null activity, never started |
| Past-due deals | Still open, date ignored | Broken promises, sorted oldest first |
| The conversation | "On track" | "$3M needs a next step or a close-lost, today" |
Here’s how I’d build it: the standing zombie strip
A one-time cleanup rebuilds to 30% within a quarter. The fix is a rate, not an event. This is the framework, the middle stage of the dissolve turned into a standing process. Locate your team on it: step 1 alone puts you ahead of most, but only step 4 makes the number stay flat.
- 1
Step 1, run the three queries and union them
Stalled, past-due, immortal. Union to one row per deal so a deal that is all three shows once. Sort by amount. The largest dead deal in the pipe is almost always near the top.
- 2
Step 2, hand each rep their own list
Not a mass report, a per-rep list in the next one-on-one. One question per deal: what is the next scheduled action and its date. Ownership of the list is ownership of the cleanup.
- 3
Step 3, force a next step or a close-lost on the call
A deal with a real next action stays and gets a logged step, today. A deal with no answer gets marked Closed Lost with a reason, on the call. No deal leaves the meeting undecided.
- 4
Step 4, wire the weekly standing report
A scheduled report of open opps with no activity in 21 days, owned by each manager, surfaces the next batch at ten deals instead of letting it pile back to 30%. This is the step that makes it a rate, not an event.
- 5
Step 5, feed the close-lost reasons upstream
The reasons reps mark reveal whether the zombies are dying in the deal (stalled) or were never real (immortal, null activity). Null-activity zombies are a targeting and lead-acceptance problem, not a rep problem. Fix the top of the funnel.
Do not mass-delete. The strip is a conversation with evidence, not a purge. A weekly report someone reads is what turns zombie pipeline from a quarterly embarrassment into a hygiene number that stays flat.
Run the null-activity query above today and sort by amount. The largest dead deal in your pipeline is almost certainly sitting near the top, green in someone’s forecast, and it will take you thirty seconds to find it. For what the survivors are worth once you weight them by stage, the second stage of the dissolve, see 3x pipeline coverage is a number that lies to you. For the forecast discipline that consumes this cleaner number, see the forecast you can defend and the operating cadence that keeps the strip running every week.
Keep reading
One email. Every week.
One email a week: an operating problem I solved or botched, with the model, the numbers, and what I would change. No roundups, no theory, unsubscribe whenever it stops being useful.
The newsletter opens soon.
Connect a provider in src/config.ts