Mert Özen Further With Every Line
Project Management Kanban — #05

Service Level Expectation and Monte Carlo: Answering "When Will It Be Done?" with Probability

Mert Özen Nov 8, 2026 11 min 1 views
Service Level Expectation and Monte Carlo: Answering "When Will It Be Done?" with Probability

For a single item the answer is the SLE ("85% within 14 days"); for many items it is a Monte Carlo simulation that samples historical daily throughput. Running 10,000 times on Bookstore data, our C# code says 30 items finish by 25 November with 50% probability and by 6 December with 85%. We cover reading percentiles from the right end, explaining forecasts to stakeholders and when the forecast goes wrong.

Version note: This post is based on version 2025.5 of The Kanban Guide; the Monte Carlo code was built with .NET 10 and run on the Bookstore board data from post 04.

Guess First

Friday, 30 October. The product owner comes to the Bookstore team: an epic for gift card support is ready, and the team has split it into 30 items that can each go to production on their own. Two questions. The first: "When will these 30 items be done?" The second comes from the marketing team: "How many items will be ready by the campaign on 27 November?"

You have the data from post 04: the team finished 66 items in the last 8 weeks, an average of 8.25 items a week. 30 / 8.25 ≈ 3.6 weeks; roughly 26 November. Would you give the product owner that date? If you did, how likely do you think it is to come true: 50%, 85%, 95%? And consider this: the team won't stop handling support requests and bugs during those four weeks. How does that change the calculation?

The Single-Item Question: The SLE

There are two kinds of "when will it be done?" questions, and each is answered with a different tool. The first is asked about a single item: "You've picked up this refund bug, when will it ship?" The answer to that is the SLE (Service Level Expectation). The Kanban Guide describes an SLE as a forecast of how long an item is expected to take from start to finish, made of a duration and a probability, and asks for it to be computed from historical cycle time data.

The calculation is just the percentile from post 04: the 85th percentile of the 66 items finished in the last 8 weeks is 14 days. So the Bookstore team's SLE is "85% of items finish within 14 days of starting." That sentence tells a customer far more than "we'll do our best," but careful: the starting point is the moment the item is pulled from Ready. If the item is still waiting in Ready, the queue in front of it also has to be counted; the SLE describes what happens after the commitment point.

The SLE and Work Item Age work together. If an item is already 10 days old and the SLE is 14 days, the remaining time for that item is better answered by "when do items of this age usually finish?" than by the SLE itself; but in practice what the team does is simple: put the item approaching the SLE at the top of the Daily's agenda.

The Multi-Item Question: When and How Many

The second kind of question is about several items and comes in two forms. In "when will 30 items be done?" the scope is fixed and the date is unknown. In "how many items by 27 November?" the date is fixed and the scope is unknown. Both are answered with the same data: historical throughput.

The opening calculation, 30 / average throughput, gives these questions a single number. The trouble is that throughput is not constant; in post 04 we saw weekly throughput swing between 5 and 11. A forecast made with the average is really an "if everything goes average" forecast, and as a probability that is roughly a coin toss. What we need is not a single date but a distribution of dates.

A Monte Carlo simulation does exactly that. The idea: each past day's throughput is one possible throughput for a future day. You simulate the future not once but thousands of times; in each simulation, for every day you pick a random day from the past and use its throughput. Once you have 10,000 possible futures, the question "how many days will 30 items take" has 10,000 answers, and their distribution gives you the probability.

The method has a single assumption: the near future will resemble the past you sampled from. We'll discuss when that assumption breaks below.

Code: 10,000 Possible Futures

We reuse the WorkItem, BoardCsv and Stats types from post 04 as they are; the new project is FlowForecast, one file:

using System.Globalization;
using Bookstore.Flow;

CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;

DateOnly today = new(2026, 10, 30);
List<WorkItem> items = BoardCsv.Load("board-history.csv");

// Sample: items that entered Done on each of the last 8 weeks' 56 calendar days, zeros included
DateOnly from = today.AddDays(-55);
int[] daily = [.. Enumerable.Range(0, 56).Select(d => items.Count(i => i.Finished == from.AddDays(d)))];
Console.WriteLine($"Sample: {daily.Length} days, {daily.Sum()} items, zero days = {daily.Count(x => x == 0)}");

// SLE: cycle time of items finished in the same window
List<int> ct = [.. items.Where(i => i.Finished >= from).Select(i => i.CycleTimeDays!.Value).Order()];
Console.WriteLine($"SLE: 85% of items finish within {Stats.Percentile(ct, 85)} days (n = {ct.Count})");

const int Runs = 10_000;
Random rng = new(2026);

// Question 1: how many items will be done by the evening of 27 November (28 days)?
DateOnly deadline = new(2026, 11, 27);
int horizon = deadline.DayNumber - today.DayNumber;
List<int> howMany = [.. Enumerable.Range(0, Runs)
    .Select(_ => Enumerable.Range(0, horizon).Sum(_ => daily[rng.Next(daily.Length)]))
    .Order()];

Console.WriteLine();
Console.WriteLine($"How many items by {deadline:yyyy-MM-dd} ({horizon} days)?");
foreach (int confidence in new[] { 50, 70, 85, 95 })
    Console.WriteLine($"  {confidence}% confidence: at least {Stats.Percentile(howMany, 100 - confidence)} items");

// Question 2: when will the 30 items of the gift card epic be done?
const int Backlog = 30;
List<int> daysNeeded = [.. Enumerable.Range(0, Runs).Select(_ => DaysUntilDone(Backlog)).Order()];

Console.WriteLine();
Console.WriteLine($"When will {Backlog} items be done (starting {today.AddDays(1):yyyy-MM-dd})?");
foreach (int confidence in new[] { 50, 70, 85, 95 })
{
    int days = Stats.Percentile(daysNeeded, confidence);
    Console.WriteLine($"  {confidence}% confidence: on or before {today.AddDays(days):yyyy-MM-dd} ({days} days)");
}

// Rough histogram of the distribution (weekly buckets)
Console.WriteLine();
foreach (IGrouping<int, int> week in daysNeeded.GroupBy(d => (d - 1) / 7))
    Console.WriteLine($"  week {week.Key + 1,2}: {week.Count() * 100.0 / Runs,5:F1}% {new string('#', week.Count() * 100 / Runs)}");

int DaysUntilDone(int remaining)
{
    int days = 0;
    while (remaining > 0)
    {
        remaining -= daily[rng.Next(daily.Length)];
        days++;
    }
    return days;
}

The sample is the number of items that entered Done on each of the last 56 calendar days. Weekends and days without a deploy stay in the list as zeros; that is deliberate. The simulation advances by calendar day, so a Saturday can draw a Monday from the sample or a zero day. Over a long horizon this converges to the average.

We give Random a fixed seed (2026) so the output is reproducible; running without a seed is fine in real use, and with 10,000 runs the result moves by a day or two. The real output:

Sample: 56 days, 66 items, zero days = 40
SLE: 85% of items finish within 14 days (n = 66)

How many items by 2026-11-27 (28 days)?
  50% confidence: at least 32 items
  70% confidence: at least 27 items
  85% confidence: at least 22 items
  95% confidence: at least 16 items

When will 30 items be done (starting 2026-10-31)?
  50% confidence: on or before 2026-11-25 (26 days)
  70% confidence: on or before 2026-11-30 (31 days)
  85% confidence: on or before 2026-12-06 (37 days)
  95% confidence: on or before 2026-12-13 (44 days)

  week  1:   0.1% 
  week  2:   5.2% #####
  week  3:  24.1% ########################
  week  4:  31.2% ###############################
  week  5:  22.2% ######################
  week  6:  11.3% ###########
  week  7:   4.2% ####
  week  8:   1.2% #
  week  9:   0.4% 
  week 10:   0.2% 
  week 11:   0.1% 
  week 12:   0.0% 

Reading the Output

40 of the 56 days in the sample are zero: weekends and days the team didn't deploy. 66 items finished on the remaining 16 days. The SLE line matches the last 8 weeks' p85 from post 04: 14 days.

We read the answer to "how many items by 27 November?" from the bottom up: in 85% of simulations at least 22 items finish, in 50% at least 32. For this question, higher confidence means fewer items. The sentence for the marketing team is "with 85% probability at least 22 items will be done by 27 November." If the gift card items needed for the campaign fit within 22, you're comfortable; if 30 are needed, your chances are a little better than a coin toss.

For "when will 30 items be done?" higher confidence means a later date. 50% on or before 25 November, 85% on or before 6 December, 95% on or before 13 December. The 26 November from the opening average calculation lands right in the middle of this distribution: the "average" forecast carries a probability of around 50%. Had you told the product owner 26 November, you would have missed it in roughly one project out of two.

The weekly histogram shows the shape of the distribution: the most likely outcome is week four (31%), but week six and beyond add up to 17%. That tail stretching to the right explains why "if everything goes well" plans are always late.

How to Tell Stakeholders

Give the forecast with its probability, not as a single date: "We forecast these 30 items will be done by 6 December with 85% probability; 25 November with 50%." The product owner decides which risk they can take. Using 95% when a contract date depends on it and 70–85% for internal planning is a common choice.

This approach comes from a different place than story point estimation. In the Scrum series' metrics post we discussed what velocity does and doesn't tell you; the upcoming Estimation and Planning series will cover story points, planning poker and release planning. The difference with throughput-based Monte Carlo is that it doesn't require estimating items one by one: you just count items. For this to work, items need to be roughly the same kind; they don't need to be exactly the same size, because size variation is already inside historical throughput.

Refresh the forecast every week. Every Monday a new week enters the data and an old one drops out; the forecast narrows or shifts. Monte Carlo is not a one-off promise but a weather report updated every week. A shifting forecast is not a failure but an early warning: if the 85th percentile date moves later two weeks in a row, the product owner still has time to talk about scope.

Limits: When Monte Carlo Gets It Wrong

If the system changed, the past doesn't describe the future. The Bookstore team changed its WIP (Work in Progress) limits in September; that's why the 8-week window starts on 5 September. Had we used May's data, the forecast would have been needlessly pessimistic. If two people leave the team, or half the team takes leave in December, the last 8 weeks' throughput won't describe the next 6 weeks; account for that either by adjusting the window or by adding a manual note to the forecast.

Little data widens uncertainty. Working with 66 items is comfortable; with a history of 15 items the percentiles and the histogram swing a lot. On a new team, give forecasts with a wide range for the first few weeks.

Throughput isn't specific to the epic. Back to the opening's second question: not all 66 items in the sample were gift card items; there were bugs, support requests and other features too. If the team keeps handling support work during these four weeks, the 30 gift card items only get part of the team's total throughput. There are two ways around it: either grow the backlog to "30 gift card items + the support and bug items expected in this period" (based on how many support items arrived per week in the past), or build the sample from feature throughput only. If you do neither, the forecast will be optimistic.

Epics grow. An epic split into 30 items can turn into 36 as work progresses; what you learn creates new items. You can add that to the forecast too, by looking at how much item counts grew in past epics.

Sampling days independently ignores the deploy rhythm. Bookstore deploys twice a week, so real throughput clusters on Tuesdays and Thursdays. Because our simulation picks days independently, a single simulation can draw five "deploy days" in a row. Over a long horizon the effect shrinks, but for short-horizon forecasts (a week or two) sampling from weekly throughput can be more realistic.

In Production

Report the seed and the window. A single line like "Forecast from 5 September–30 October throughput, 10,000 runs" makes the forecast reproducible and open to discussion. If you run without a seed, say that two runs can differ by a day or two; otherwise people will take the difference for a bug.

Don't overdo the number of runs. 10,000 runs finish in under a second on this data and the percentiles no longer move. A million runs won't make the forecast more accurate; the uncertainty comes not from the simulation but from how well the past describes the future.

Automate the forecast. Adding this calculation to the weekly metrics job from post 04 means sending the product owner an up-to-date "85% date" every Monday. The forecast stops being the output of a meeting and becomes a signal that is always visible.

Common Pitfalls

Forecasting with the average is the most common pitfall. "We do 8 items a week, so 30 items take 4 weeks" is a 50% forecast that sounds like a 100% promise.

The second pitfall is reading the percentile from the wrong end. For "how many items?" 85% confidence is the 15th percentile of the distribution; for "when?" 85% confidence is the 85th percentile. That is why the code has the line Stats.Percentile(howMany, 100 - confidence); getting that line wrong means reporting the most optimistic scenario as 85% safe.

The third is dropping zero days from the sample. If you drop the zeros because "zero days are meaningless, we don't work weekends anyway" and still advance the simulation by calendar day, you give every calendar day the throughput of a working day. In this data the error is even bigger because days without a deploy are zero too: the 16 non-zero days average 4 items a day, while the real calendar average is 1.2; the forecast comes out several times too optimistic. Keep the zeros.

The fourth is turning the forecast into a target. "The 85% date is 6 December" is a forecast. If a manager sends it back to the team as "the 6 December deadline," the team tries to make the date by raising WIP or bending Done, and corrupts the data the next forecast depends on.

A Small Experiment

★☆☆ Run the simulation with 4, 8 and 16 week windows. How does the 85% date for the "30 items" question change? The 16-week window includes the period before September; even if the result barely changes, why is that risky?

★★☆ Build the sample from weekly throughput instead of daily (the last 8 weeks' 8 values) and advance the simulation week by week. How different are the 50% and 85% dates from the daily sample?

★★★ Make the backlog realistic: compute how many Support and Bug items finished per week on average in the last 8 weeks, and in every simulation add that many items to the backlog for each simulated week. By how many days does the 85% date of the 30 gift card items shift?

We have measured and forecast. In the next post we start using these numbers every day: running the Daily from the right of the board to the left, blocked items, the cost of an expedite policy, and how the Bookstore team solved its Code Review bottleneck with data.