Estimation
An estimate is a forecast made under uncertainty, not a promise. Its job is to inform a decision and surface risk, not to be proven right. The moment an estimate is treated as a commitment, people stop estimating honestly and start negotiating, and the number loses all of its value.
Why this matters
The playbook already assumes you can estimate. The "definition of ready" in Communication & Collaboration requires every ticket to be estimated before it enters a sprint, and the career ladder in Learning & Growth expects a mid-level engineer to "estimate work accurately." Until now we never said how. This section closes that gap.
Estimation is where Integrity and Care meet delivery. Clients plan budgets, launches, and their own commitments around the numbers we give them, so an optimistic guess dressed up as a date is not harmless, it is a small breach of trust that compounds. A team that estimates honestly (with ranges, stated assumptions, and the discipline to re-estimate when scope moves) keeps the predictability that client relationships are built on. A team that quotes single dates to look confident spends the rest of the project explaining why it slipped.
The standard
What an estimate is, and what it is not
Three words get used interchangeably and should not be:
| Term | Who owns it | What it means |
|---|---|---|
| Estimate | The people doing the work | An honest forecast of effort, with uncertainty attached. "Most likely 3 days, could be 5." |
| Target | The business or client | A desired outcome. "We want this for the trade show on the 20th." |
| Commitment | The team, deliberately | A date the team agrees to hit, derived from the estimate plus a chosen confidence buffer. |
The failure mode is collapsing all three into one number. A target is not an estimate (wanting it sooner does not make it shorter). An estimate is not a commitment (a forecast becomes a promise only when the team consciously adds buffer and agrees to it). Keep them separate in your own head and in conversations with clients, and most estimation conflict disappears.
The other rule: estimates are owned by the people who will do the work. An estimate handed down by a manager or a salesperson is a target wearing an estimate's clothes. If the engineer who picks up the ticket did not shape the number, it is not their estimate and they will not stand behind it.
Investigate before you estimate
An honest three-point estimate is downstream of how well you understand what you are about to build or change. The PERT formula turns judgment into a number, it cannot manufacture the judgment. Before you write down O, M, or P, do the detective work: figure out what you are actually walking into.
What to look for depends on whether the work is new or you are cutting into something that already ships.
New work (a new app, a new service, a feature area nobody has built yet): the risk lives in the unknowns of creation.
- User personas. Who uses this, and how many distinct kinds of "who" are there? One persona and three personas with different permissions are different estimates, even for the same screen.
- Scale. How many users, how much data, how much traffic. A CRUD screen for 50 internal users and the same screen in front of 500,000 public users are not the same estimate, even though the first draft of the code looks identical.
- Infrastructure. What already exists and what has to be stood up. Reusing an existing Postgres instance and CI pipeline is a different estimate than provisioning a new environment, secrets, and deploy pipeline from nothing.
- Design. Does a design exist, and is it a finished Figma file or a verbal description? Undesigned UI work is not small, it is unestimated. The design work is its own task, and skipping it is how "just build the form" turns into three rounds of layout rework mid-sprint.
Existing work (the more common case at S&P: a change to an app that is already live): the risk lives in what you might break, not what you have to invent.
- Other user roles. Who else touches this code path? A change scoped to the admin flow can quietly change behavior for a support role or an external API consumer hitting the same endpoint.
- Backwards compatibility. If a database change is involved, what reads the old shape today? A nullable column addition is usually safe. Renaming a column, tightening a constraint, or dropping something another service still reads is where the real pessimistic case lives.
- Migration mechanics on real data. Compatibility is not the only migration risk. How long the migration itself takes to run, and whether it needs to be online or zero-downtime, is a different question from whether the new shape is compatible. A migration that finishes instantly against a development table can lock a production table for minutes. Check data volume and existing data quality (nulls, duplicates, orphaned rows) before you size this, cleanup is often the real work.
- Other callers. Search for every consumer of the function, endpoint, or table before you touch it. A one-line change to shared code carries an N-caller blast radius, and N is exactly what your estimate needs to reflect.
- Existing fragility. Check recent incidents and bug tickets for the area you are about to touch. "It works but nobody trusts it" is real information, and it belongs in your pessimistic number, not in a surprised Slack message three weeks later.
Regardless of new or existing, also check:
- Who is actually doing it. Skill fit changes the estimate more than the ticket does: an engineer unfamiliar with this codebase or this kind of integration needs a wider P than one who has shipped three of these already. Availability matters too, a person split across two tickets, or about to go on leave, does not deliver at the rate the estimate assumes.
- External dependencies. A third-party API's rate limits and documentation quality, another team's deliverable this work is blocked on (see Cross-team collaboration), or content, credentials, and access the client has to provide before you can start. Anything outside your own team's control belongs in the pessimistic case, not in a footnote.
- Non-functional requirements. Performance and load targets, accessibility, i18n, browser and device support, and security or compliance review (see Security, real weight for regulated clients). These are invisible in a happy-path demo and expensive to retrofit once the feature is "done."
- Rollout mechanics. Does this need a feature flag or a staged rollout, or does it ship all at once? Is there a rollback plan? Does the release collide with the client's own calendar (a launch, a freeze, an event)? Release planning starts here, not after the code is written.
- Approval latency. A mandatory design, legal, or security sign-off before ship is not coding time, but it is real elapsed time, and it belongs in the estimate the same way QA turnaround does.
- Contract type. Fixed-price work means a bad estimate comes out of margin directly, so widen P more and lean on a higher confidence level. Time-and-materials gives more room to correct mid-flight, but it still earns a range, not a guess dressed as a date.
- What happened last time. Before estimating from scratch, check whether similar work has been estimated before and how it actually went. That is the payoff of the Tracking actuals and improving habit later in this section, but only if you look before you estimate, not only after.
Use AI to do this faster, not to skip it. Ask it to trace callers of the code you are about to change, summarize what a migration would affect, or list who a permission check gates, then verify what it finds against the actual codebase before you trust it. AI is fast at surfacing "what else touches this" and unreliable at knowing whether what it found is complete, so the verification is yours.
You are accountable for this investigation, not only for the number it produces. If an estimate is wrong because of something a few minutes of looking would have surfaced, the fix is not "the formula failed," it is "the investigation was skipped."
Dev notes: writing down what the estimate assumes
An estimate without its assumptions attached is a number that will eventually look wrong for reasons nobody can reconstruct. A dev note is where the investigation above gets written down: the ideas and assumptions the estimate rests on, captured at the moment you made it.
Two things matter more than the format:
- Point in time, not living documentation. A dev note describes what you believed when you estimated, not an ongoing spec. Add it as a comment on the ticket rather than editing it into the description, so it stays a dated snapshot. When an assumption turns out wrong, the fix is a new comment or a re-estimate, not a silent edit that erases what the original number was actually based on.
- Written for people who were not in your head. The audience is not just you. The client, the delivery manager, the CTO, the CEO, whoever reads the estimate later without the context you had, all rely on the dev note to understand why the number is what it is and what would change it. A useful test: if the client later asks "why did this take longer," a good dev note already answered that question before it was asked.
A short dev note answers three things:
- What did the investigation turn up? (the personas, scale, other roles, or backwards-compatibility findings from above)
- What is explicitly out of scope? (the exclusions the Checklist already asks you to state to the client)
- What would change this estimate if it turned out false?
Worked example, continuing the CSV export from the PERT walkthrough above: "Assuming the existing /reports endpoint's auth and pagination can be reused as-is. Have not confirmed whether the export needs the same row-level permissions as the report view; if it does, add 1-2 days. Not accounting for files over 100k rows, streaming would be a separate estimate."
Three sentences, and a delivery manager now knows exactly what to watch for and exactly which question to ask if the permission assumption turns out to matter.
Dev notes live next to the estimate in Jira, following the same Jira hygiene habit that already asks you to comment when a ticket runs long. They are what "dependencies and assumptions are written down" in the checklist actually means in practice, and they are owned by whoever produced the estimate: if the assumption changes, updating the note is on you, not on whoever reads it next.
Three-point estimation (PERT)
Single-number estimates hide the one thing that matters most: how uncertain you are. "5 days" tells the reader nothing about whether you mean "5 days, easy" or "5 days if nothing goes wrong, and plenty could." Three-point estimation makes that uncertainty explicit.
For each task, capture three numbers:
- Optimistic (O): everything goes right. The realistic best case, not a fantasy.
- Most likely (M): your honest single-point guess if you had to give one.
- Pessimistic (P): the realistic worst case. Not the apocalypse, but "the integration fights back, the requirement was fuzzier than it looked, a dependency is late."
PERT combines them into a weighted expected value and a measure of spread:
Expected effort E = (O + 4M + P) / 6
Standard deviation sigma = (P - O) / 6
Variance = sigma^2
The weighting (4 parts most-likely to 1 part each of the extremes) reflects that the middle is where reality usually lands, while still letting a long worst-case tail pull the expected value upward. That upward pull is the point: it is the math quietly correcting for the optimism every engineer carries.
Worked example: a CSV export endpoint.
- O = 1 day (the data model is clean, a library does most of it)
- M = 2 days (the realistic case)
- P = 5 days (pagination, large-file streaming, and edge-case formatting turn out to be real work)
E = (1 + 4*2 + 5) / 6 = 14 / 6 = 2.33 days
sigma = (5 - 1) / 6 = 4 / 6 = 0.67 days
So the honest answer is "about 2.3 days, plus or minus 0.7," not "2 days." Notice the expected value (2.33) sits above the most-likely guess (2): the wide pessimistic case has correctly nudged it.
Rolling estimates up with the S&P template
Per-task numbers are only useful once they roll up into a forecast for the whole feature or project. The S&P PERT estimation template does this for you: enter O, M, and P per task and it computes E, sigma, and the totals.
The roll-up math is not "add up the expected values and add up the standard deviations." Expected values add, but variances add, standard deviations do not:
Project expected effort = sum of each task's E
Project variance = sum of each task's variance (sigma^2)
Project sigma = sqrt(project variance)
| Task | O | M | P | E | sigma | variance |
|---|---|---|---|---|---|---|
| CSV export endpoint | 1 | 2 | 5 | 2.33 | 0.67 | 0.44 |
| Auth on the new route | 2 | 3 | 7 | 3.50 | 0.83 | 0.69 |
| Frontend download button + states | 0.5 | 1 | 3 | 1.25 | 0.42 | 0.17 |
| Project | 7.08 | 1.14 | 1.30 |
Project sigma is sqrt(1.30) = 1.14 days, not the 1.92 you would get by adding the three standard deviations. This is the most useful property of the method: because risks partly cancel out, a project is proportionally more predictable than its riskiest single task. Use the sigma to express confidence, assuming a roughly normal spread:
- E (about 7.1 days): roughly 50/50. Half your projects quoted this way finish late.
- E + 1 sigma (about 8.2 days): about 84% likely to be enough.
- E + 2 sigma (about 9.4 days): about 98% likely to be enough.
That is how you turn a spreadsheet into a sentence for a client: "Most likely around 7 days; we would commit to 9 to be safe." You are no longer guessing at a buffer, you are choosing a confidence level.
Two honest caveats the template does not enforce, so you must:
- The math assumes the tasks are independent. In reality, if one task runs long because the requirement was vague, related tasks often slip for the same reason. Correlated risk makes the real spread wider than the formula suggests. Treat the computed sigma as a floor on your uncertainty, not a ceiling.
- Classic PERT sums along the critical path (the longest chain of dependent tasks in a network), not every task in the backlog. For most S&P feature work, sum the tasks on the longest dependency chain. If work is genuinely parallel across people, estimate each person's chain separately rather than summing everything into one inflated number.
Choosing the right tool: PERT, story points, or t-shirt sizing
PERT is precise but it costs time. Do not apply it to everything.
| Method | Best for | Why |
|---|---|---|
| Three-point / PERT | Feature and project forecasts, anything a client commitment hangs on | Produces a defensible range and a confidence level. Worth the effort when the cost of being wrong is real. |
| Relative sizing / story points | The sprint backlog, sprint-over-sprint planning | Fast, and velocity turns points into a forecast over time without per-task time guessing. |
| T-shirt sizing (S/M/L/XL) | Early roadmap and triage, before requirements are firm | Honest about coarse uncertainty. Stops you from inventing false precision on work you barely understand. |
The anti-pattern is precision theatre: running a full three-point estimate on a one-line bug fix, or quoting "0.8 story points." Match the effort of estimating to the cost of being wrong. A one-line fix is "small, do it today." A three-month client commitment earns the spreadsheet.
From estimate to commitment
An effort estimate is not a delivery date. Turning one into the other means accounting for everything that is not heads-down coding:
- Non-coding time is most of the slip. Code review turnaround, QA and bug-fix cycles, the deploy itself, standups and meetings, context-switching between tickets. If your estimates only cover writing code, they are systematically and predictably short.
- Respect the definition of ready. Per Communication & Collaboration, a ticket that lacks clear acceptance criteria cannot be estimated honestly. If you cannot give a sane pessimistic number, the task is not ready, it is research. Estimate the research as its own task (a spike) and re-estimate the work once you know more.
- Estimates feed planning, they do not replace it. Project-level forecasts inform the release cadence and stakeholder alignment (S&P ships at the end of each sprint, so estimates frame which sprint a feature realistically lands in), and per-ticket estimates feed sprint planning. The estimate is an input, the plan is the decision.
When you commit to a client, commit to a confidence level, not the bare expected value. Quoting E means roughly half your features ship late. Quoting E + 1 or 2 sigma is the difference between "usually on time" and "the client stopped trusting our dates."
Tracking actuals and improving
Estimation is a skill, and skills only improve with feedback. The loop is cheap and most teams skip it:
- Record what actually happened. Capture actual effort against the estimate. Jira hygiene already asks you to comment when a ticket runs long ("if a ticket takes twice as long as estimated, a brief comment explaining why helps future estimation"), this is what that note is for.
- Look for the pattern, not the miss. One task running over is noise. The same person or team consistently underestimating a category of work (anything involving third-party integrations, say) is a signal you can correct for next time.
- Bring it to the retro. Estimation accuracy is a legitimate, low-drama retrospective topic. The goal is calibration, not blame. A team that knows it underestimates integrations by 50% and adjusts is estimating well, even when the first guess was off.
Critical thinking
- Estimates are not commitments, and padding in secret destroys the difference. The honest way to be cautious is a wider pessimistic number and an explicit confidence level the client can see. Quietly inflating a single number to protect yourself trains everyone to distrust every number you give, including the ones you did not pad.
- The planning fallacy is not a personal failing, it is a species-wide bias. People underestimate their own tasks even when they have watched identical tasks run long before. PERT only helps if the pessimistic point is genuinely pessimistic. If your P is just M plus a little, you have not escaped the bias, you have decorated it.
- #NoEstimates has a real point. For well-understood work sliced into small, similar pieces, counting throughput (how many tickets the team actually closes per sprint) forecasts more accurately than estimating each item, because it measures reality instead of predicting it. Reach for per-task estimation when the work is novel or a commitment depends on it, not by reflex.
- Garbage in, garbage out. The formula cannot rescue a vague requirement. A confident-looking E computed from three numbers you pulled out of the air is more dangerous than an honest "we do not know enough to estimate this yet," because it launders a guess into something that looks like analysis.
- Three points from one person is one person's blind spots. For anything that matters, estimate together. The value of planning poker or a quick group three-point pass is not the average, it is the conversation when two people give wildly different P values: that gap is a hidden assumption or an unspoken risk, surfaced before it bites.
- Investigating has the same failure mode as estimating: theatre. Interviewing five stakeholders about personas for a two-day feature is precision theatre in a different costume. Scale the digging to the size and risk of the decision, the same judgment call as choosing PERT over t-shirt sizing above.
Checklist
For every task you estimate
- Optimistic, most-likely, and pessimistic values are all captured, not just a single number
- The pessimistic value reflects a realistic bad case, not the most-likely value with a token margin
- Non-coding time (review, QA, deploy, meetings) is included or accounted for elsewhere
- For new work: personas, scale, infrastructure, and design status are checked, not assumed
- For existing-system work: other user roles, backwards compatibility, migration runtime and data quality, and other callers of the code are checked, not assumed
- External dependencies, required approvals, and rollout mechanics (flag, staged rollout, rollback) are identified before sizing it
- A dev note capturing assumptions and open questions is added to the ticket as a comment
- The task meets the definition of ready; if not, it is estimated as a spike instead
For every project or feature forecast
- Task estimates are rolled up through the S&P template (variances summed, not standard deviations)
- A range and a confidence level are communicated, never a single bare date
- The chosen commitment date sits at a deliberate confidence level (E + 1 or 2 sigma), not at E
- Assumptions and excluded scope ("we are not doing X") are stated explicitly to the client
- Contract type, who is actually doing the work, and actuals from similar past work are factored into the confidence level you choose
Ongoing
- Actual effort is recorded against the estimate
- Estimates are revised when scope changes, rather than left stale
- Estimation accuracy is reviewed periodically in retrospectives, for calibration not blame
AI tips
- Decompose a feature into estimable tasks. Paste the requirement or ticket and ask AI to break it into a task list, then sanity-check the breakdown. AI is good at remembering the steps you forget (migrations, error states, the deploy), which are exactly the tasks that get left out and cause slips.
- Generate starting points for O, M, and P, then correct the P. AI can propose three-point values from a task description, but it skews optimistic and its pessimistic case is usually too tame. Treat its O and M as a reasonable first draft and widen the P yourself based on what you know about this codebase and client.
- Have AI hunt for risks that should widen the pessimistic estimate. Ask "what could make this take much longer than expected?" It surfaces integration edge cases, auth and permission complexity, and data-migration gotchas that justify a larger P. This is more valuable than asking it for the estimate itself.
- Use AI to trace blast radius on existing systems, then verify by hand. Before estimating a change to code that already ships, ask AI to find other callers of the function or endpoint, other consumers of the table you are about to migrate, or the roles gated by the permission check you are touching. It is faster than grepping a NestJS monorepo by hand, but it can miss call sites or invent ones that are not there, so confirm what it surfaces against the real code before it changes your pessimistic number.
- Ask AI to mine similar past tickets before estimating fresh. If comments or PRs from a similar piece of past work are available, have it summarize what actually happened and how far off the original estimate was. This is a faster version of checking history before you estimate, and it stops you from calibrating off memory alone.
- Draft the client-facing summary from the spreadsheet. Give AI the rolled-up E and sigma and ask it to write the range in plain, non-technical language ("most likely around X, we would commit to Y"). It is good at translating the math into a sentence a non-engineer can act on, the same skill described in Communication & Collaboration.
- Do not let AI invent confidence. AI has no memory of your team's velocity or this client's history, so any number it gives is a generic prior, not a calibrated estimate. Use it to structure and pressure-test your thinking, never as the source of the final commitment.
Resources
S&P internal:
- S&P PERT estimation template (Google Sheets) -- enter O/M/P per task, get E, sigma, and the rolled-up forecast
- S&P Standardised Learning & Development -- where estimation accuracy fits into the growth framework
Playbook cross-references:
- Communication & Collaboration -- definition of ready, sprint planning, Jira hygiene, translating estimates for clients
- CI/CD & Release Process -- sprint-based release cadence and stakeholder alignment that estimates feed into
- Learning & Growth -- the career ladder expectation to estimate work accurately
- Architecture & System Design -- back-of-the-envelope capacity estimation (sizing infrastructure, a different kind of estimate from effort)
- Engineering Principles -- decision records, where "estimated cost" frames a choice
External references:
- Program Evaluation and Review Technique (PERT) -- the method and its three-point formula
- The planning fallacy -- why we systematically underestimate, and why P matters
- Evidence-Based Scheduling (Joel Spolsky) -- estimating from historical actuals rather than guesses
- #NoEstimates (overview) -- the case for forecasting from throughput on well-sliced work
- Steve McConnell, Software Estimation: Demystifying the Black Art -- the definitive practical treatment