Monte Carlo delivery forecasts

A Monte Carlo forecast is a defensible answer to "when will this be done?" derived from your team's real shipping history, not from a stakeholder's flinch. Every module (epic) and every sprint in Ithura carries a small forecast pill on its header showing a P50 / P85 / P95 completion-date band, computed by simulating 10,000 possible futures against the last 90 days of your team's actual throughput.

Drag scope in, the band slides right. Drag it out, the band slides left. The number is defensible because it is derived from the same days the team actually shipped. No fake target dates, no astrology, no "gut says end of Q3".

What you see

A small pill on the module or sprint header, like ≈ Oct 14. Hover it for the full band:

Monte Carlo forecast
P50 (most likely)     Oct 3
P85 (safe commit)     Oct 14
P95 (worst plausible) Oct 22

18 open · 2.1/day avg
Based on last 90 days of throughput · 10,000 sims
  • P50 is the date half of the simulations finished by. "Most likely" completion date.
  • P85 is what most teams cite as commit-able. Land dates here.
  • P95 is the widest plausible finish.
  • Open is the current count of unresolved issues in the scope.
  • Avg is the arithmetic mean of the throughput history the sampler used.
  • Sims is the run count of the Monte Carlo simulation (10,000 by default).

Drag scope in or out of a sprint / assign or unassign issues to a module: the band recomputes on the next hover.

How it works

The sampler runs 10,000 simulations. Each simulation walks forward day-by-day from today, draws a random daily throughput from the team's last 90 days of completed-issue counts (with replacement), and stops when the cumulative throughput reaches the remaining scope count.

The distribution of "days needed" across all 10,000 runs is sorted and the P50 / P85 / P95 boundaries become the returned dates.

Why bootstrap sampling, not a Poisson or Gaussian model: real team throughput is bursty in ways parametric models miss (two-week planning cycles, quarter-end pushes, holiday quiet periods). Drawing from real observed days preserves those patterns for free. This is the same reason ActionableAgile (the Jira plugin) and other credible forecasters use bootstrap sampling.

Why zero-completion days matter: the sampler needs to know about weekends and quiet days. Those are included as explicit 0 entries in the history, so a sim can draw a zero-day and correctly model a weekend gap. A history that omits zero days produces optimistic forecasts.

Why 90 days: long enough to capture two full sprint cycles + one quarter's holidays, short enough that team composition changes don't rot the signal.

When you'll see "Forecast pending"

The pill renders Forecast pending if the workspace has zero completed issues in the last 90 days. Ship a few issues to seed the history; the pill flips to a real forecast automatically after the first completion.

For teams with less than 14 days of history, the tooltip carries a "Based on limited history; will sharpen as the team ships more" note. Take the number soft in that window.

API

For automation, dashboards, or your own reports:

GET /workspaces/{slug}/projects/{projectID}/modules/{moduleID}/forecast/
GET /workspaces/{slug}/projects/{projectID}/cycles/{cycleID}/forecast/
GET /workspaces/{slug}/projects/{projectID}/sprints/{cycleID}/forecast/

Returns:

{
  "scope": "module",
  "scope_id": "8c9063b3-...",
  "remaining_issues": 18,
  "p50": "2026-10-03T00:00:00Z",
  "p85": "2026-10-14T00:00:00Z",
  "p95": "2026-10-22T00:00:00Z",
  "history_days": 90,
  "avg_throughput": 2.1,
  "samples_used": 10000,
  "note": ""
}

Auth: workspace-member API token. Zero-cost recompute (~2ms) so a dashboard can hit it every minute without concern.

  • Analytics and insights: the historical throughput chart that feeds this forecast.
  • Estimates: how to configure per-project estimate scales; estimate points are not yet weighted in v1 (issue count is the unit).
  • Sovereign: the forecast runs entirely on your Postgres. No AI service, no cloud dependency.

Known limits (v1)

  • Forecasts weight each remaining issue equally. Estimate-point weighting is a v2 follow-up.
  • Cross-team throughput isn't yet separable, so a workspace-scoped forecast covers all projects. Per-team throughput history is a v2.
  • No caching: the sampler runs inline on every request. Cheap enough today, but a caching layer keyed on (scope, last_mutation_at) is the next optimisation if forecast rendering becomes a hot path.