Estimation and planning
An estimate is a forecast with a range, not a promise. Break the work into small pieces, count the hidden work, and do a short investigation first for the unknown part. Give the number with a range, assumptions and risks, and update the estimate whenever you learn something new.
Author: bezzad
The problem: “just three days”
The product manager of our online shop asks in the hallway: “How long will the discount code take?” The developer thinks for a moment and says: “Three days.”
The manager tells this number to the marketing team. Marketing plans the campaign for next week.
The work takes three weeks. Why?
- The payment gateway had a separate API for discounts that nobody knew.
- An admin panel was needed so the marketing team could create codes themselves. Nobody had thought about it.
- Review, testing and deployment were not counted in those “three days”.
- In the middle of the work, two urgent bugs came from another team.
The developer did not do bad work. The problem was that a quick guess was heard as a promise.
Estimate, target and commitment
People often mix up these three words. But they are three separate things:
- Estimate (Estimate). An honest forecast. “Most likely between 8 and 14 days.”
- Target (Target). What the business needs. “It must be ready before the Nowruz campaign.”
- Commitment (Commitment). The promise we give after comparing the estimate and the target. “We will deliver the simple version by that day.”
If the target is earlier than the estimate, making the estimate number smaller does not help. The work takes just as long. The right way is to change the scope of the work: “For the campaign, only percentage codes. Fixed-amount codes and the full admin panel come later.”
Why do we usually underestimate?
- We think of the best case. In our mind, the work moves forward without any problem.
- We forget the hidden work. We only count “writing code”. Not review, testing, database changes, deployment and meetings.
- A workday is not full. Meetings, helping a colleague and urgent bugs take part of every day.
- We do not see the unknowns. An unfamiliar API, or old code that nobody knows.
- Pressure for a small number. When someone is waiting in front of us, it is easier to say a smaller number.
The cone of uncertainty
At the start of the work, we do not know many things. So our estimate has a wide range. The further we go and the more we learn, the narrower the range gets. We call this shape the “cone of uncertainty” (Cone of Uncertainty).
This shape has two lessons:
- An estimate at the start has a wide range. If someone wants an exact number in the first meeting, the most honest answer is a wide range.
- Repeat the estimate. When the requirements are clear, when the design is ready, and when part of the work is done. Each time, the range gets narrower.
Breaking down the work
You cannot estimate a big task well. You can estimate a small one. So we break the discount code into a few pieces:
A few simple rules for breaking down work:
- Each piece should be small. If a piece is more than a few days, we do not understand it yet. Break it again.
- Each piece should have a visible result. “Table and model ready and tested”, not “work on the backend”.
- Write down the hidden work. Count it separately so it is not forgotten.
- Separate the unknown part. For the payment gateway, first do a short, time-boxed investigation (Spike). For example, “We spend one day to try the gateway API.” Then estimate that part.
Three-point estimation
A single number carries little information. For each piece, we give three numbers:
- The best case. If everything goes well.
- The most likely case. Our real guess.
- The worst case. If a few things go wrong together, but not a disaster.
A common formula to combine these three numbers is the PERT formula. It gives more weight to the most likely number, but it also counts the worst case:
public sealed record TaskEstimate(string Name, double Best, double Likely, double Worst)
{
// PERT (three-point) expected value, in days
public double Expected => (Best + 4 * Likely + Worst) / 6;
}
TaskEstimate[] tasks =
[
new("Model and table", 1, 1.5, 2),
new("Rules and tests", 2, 2.5, 4),
new("Checkout page", 1, 2, 3),
new("Admin panel", 1, 1.5, 2),
new("Hidden work", 1, 2, 4),
];
var expected = tasks.Sum(t => t.Expected);
Console.WriteLine($"Expected: {expected:F1} days"); // 9.8
Console.WriteLine($"Range: {tasks.Sum(t => t.Best)}-{tasks.Sum(t => t.Worst)} days"); // 6-15
What do these numbers tell us?
- The expected number is about ten days. Not three days, and not the sum of the most likely numbers, which is nine and a half days.
- The full range is from 6 to 15 days. But it is unlikely that all tasks reach their worst or best case together. So a more realistic range is narrower than this.
- The payment gateway is not counted yet. After the short investigation, we add it too.
How do we say the number?
A good estimate is not just a number. It has four parts: a range, confidence, assumptions and risks.
Bad
“Three days.”
- It has no range.
- It is not clear what is counted in it.
- The listener hears it as a promise.
Good
“Most likely between 8 and 14 working days. This number includes testing, review and deployment. I assumed the admin panel can only create and disable codes. The biggest risk is the payment gateway. Tomorrow I will spend one day investigating it, and the day after I will give a more exact number.”
If someone in the hallway wants a number right away, say: “Right now I only have a very rough guess. By tomorrow I will give a proper estimate.” This one day is much cheaper than three weeks of lost trust.
During the work
An estimate is not said once and forgotten:
- Measure progress in small pieces. “Three of five pieces are done” is more exact than “seventy percent of the work is done”.
- Report delays early. If on day three you see the work will be late, say it that same day. Bad news early gives the business time to choose. Bad news late is only a surprise.
- Cut scope, not quality. If time is short, remove a part or move it later. Removing tests makes the work more expensive later.
- Compare the estimate with reality. After a few tasks, you may see that your work usually takes one and a half times your estimate. This number is very valuable for your next estimates.
Common mistakes
| Mistake | Result | Right way |
|---|---|---|
| A single number, without a range | The listener hears it as a promise. | A range, assumptions and risks. |
| Estimating a big task as one piece | Many things are not seen. | Break it into pieces of one or two days. |
| Counting only coding time | Testing, review and deployment are left out. | Write down the hidden work separately. |
| Lowering the estimate to reach the target | The work takes just as long, it only becomes clear later. | Reduce the scope of the work. |
| Estimating the unknown part without investigating | Most of the delay comes from this part. | First a short, time-boxed investigation. |
| Hiding a delay until the last day | Trust is lost, and nobody has time to react. | Give bad news early. |
| Estimating work for the person who will do it | The number does not match that person’s speed and knowledge. | The person who does the work takes part in the estimate. |
Summary in six lines
- An estimate is a forecast. A target is what the business wants. A commitment is the promise we give after comparing the two.
- At the start the range is wide. As the work moves forward, repeat the estimate.
- Break the work into small pieces and count the hidden work separately.
- For the unknown part, first do a short, time-boxed investigation.
- Estimate with three numbers and give the result with a range, assumptions and risks.
- Report delays early, and if time is short, cut scope, not quality.