Skip to content
indraft
Start free

Cookbook

Forecast the quarter, and find out why you lose

Ask for the number, then ask the harder question underneath it: not how much is in the pipeline, but why the deals that left it did.

The situation

It is the end of the month and somebody wants a number. You also want to know something more useful than the number, which is what keeps happening to the deals you do not win.

What must be true when you are done

  • A pipeline total you can defend, computed over every deal rather than a sample.
  • The same total split the way the question was actually asked: by stage, by quarter.
  • A count of why you lost, from a fixed list rather than free text.

The number

You

What is in the pipeline, by stage? Then the same thing by expected close quarter.

Stage Value
Qualifying 104,000
Scoping 224,000
Proposal 337,000
Won 186,500
Lost 54,000

Agent

2026-Q3 905,500

The database computes this over every matching deal. That matters more than it sounds: the obvious way to build this feature is to fetch a page of deals and add them up in the agent, which is correct in a demo and silently the total of a sample once you pass a hundred records. Nothing on the page would tell you which one you were looking at.

Quarters follow your financial year, not the calendar, if you have told the workspace when yours starts. Ask for Q3 and you get your Q3.

That total counts the closed deals too, which is usually not the number somebody means. Filter to the open ones and you get 665,000, and the same question weighted by the probability standing on each deal gives 279,800. Both are computed from figures already on the records: the weighting is arithmetic, not a prediction. If the weighted number is the one you are actually being asked for, it has a recipe of its own, including what it leaves out and how to keep it so you can check it later: weight the pipeline, and check last month's call.

Why you lose

A reason is only useful if it is countable, so make it a fixed list rather than a text box.

You

Add a lost reason to deals: price, timing, no decision, chose a competitor, lost to build. Then tell me how the lost deals break down.

Agent

price 1(no reason set) 8

Because it is a fixed list, the agent cannot invent a sixth reason and neither can anyone else. Try to store one and the refusal hands back the options it will take:

Agent

refused: lost_reason is not one of the options this field allows. Options: price, timing, no decision, chose a competitor, lost to build

So the count stays a count. Free text would have given you sixty spellings of "too expensive" and nothing to group by.

The refusal worth reading

Ask to group by something the database cannot answer quickly and you get a refusal that explains itself, along with the list of what you can group by.

Agent

refused: opportunity cannot be grouped by name. Grouping by a field that is not indexed, or that has a different value on nearly every record, would have to read every one of them and would hold up every other read and write in your workspace. Available: status, stage_id, pipeline_id, owner_actor_id, currency, expected_close_date, ...

That is not a limitation to route around, it is the reason your reads stay fast while somebody else is writing. Mark a custom field as searchable when you create it and it joins the list.

Verify it

  • Add the stage totals up by hand once. They should match the total you get without a grouping. If they do not, something is filtered that you did not mean.
  • Check the won and lost rows are there. A forecast that silently drops closed deals is a different question from the one you asked.

Run it again

Weekly for the pipeline, monthly for the reasons. The reasons only become interesting once there are enough of them to show a pattern, and the first month of data will tell you mostly that your list of reasons is wrong.