Русская версия подготовлена на основе моей статьи на Хабре: «Throughput: как научиться перестать гадать сроки и начать их предсказывать через симуляцию Monte-Carlo».

Throughput — базовая метрика, с которой начинается разговор о предсказуемости команды. Сначала нужно научиться читать сам поток: по периодам, вариативности и типам работы. Прогнозирование через Monte Carlo — следующий шаг, которому посвящена отдельная статья.

Преамбула

Заходишь убитый в пятницу в бар. Заказываешь пивной сет. Официант обдумывает в голове: “За последний час у нас было приготовлено 12 заказов, сейчас в работе 4 заказа, новый сет будет пятый в очереди”, а потом информирует нас: “Ваш заказ подадут через 20–25 минут.”

Официант оценивает очередь заказов по историческим данным

Никаких субъективных оценок сложности, просто прикинул исторические данные и сделал прогноз. Голубая мечта — чтобы IT-команда планировала так же просто, честно и (относительно) предсказуемо. Мы можем попробовать приблизиться к таким прогнозам.

Это практический пост с паттернами и примерами. Я не делаю из Throughput волшебную метрику. Задача проще: показать, как читать пропускную способность команды без споров о story points и субъективной сложности задач.

Throughput (пропускная способность) — одна из главных метрик потока

Сред Throughput по спринтам. Со стороны выглядит ровно и предсказуем

Throughput — количество завершённых задач за период времени. Если команда закрыла 8 задач за неделю, throughput = 8 задач/неделю. Просто, объективно, почти невозможно подделать. Любую метрику при желании можно хакнуть, Throughput не исключение.

Или вот: команда завершила 15 user stories за 2 недели → throughput = 7.5 историй/неделю.

Другие метрики потока — Cycle Time, Lead Time.

Три среза, через которые мы анализируем Throughput

Временные периоды

Важно понимать, какой временной период для вас значим и достаточно ли его для анализа.

Мы с вами часто считаем Velocity на уровне спринта: количество готовых элементов или пресловутые Story Points. Для статистики спринтового масштаба мало: двухнедельный спринт даёт всего 26 точек данных в год. Это нижняя граница для базового анализа, внутренние паттерны на таком масштабе почти не видны.

Если замерять чаще, появляется больше сигнала:

  • Ежедневно: 260 точек/год — становятся видны паттерны по дням недели
  • Еженедельно: 52 точки/год — достаточно для трендов

На недельных отрезках Throughput выглядит немного иначе

Дневная динамика показывает что в самые пиковые дни команда просто закрыла несколько задач. Еще удивительно что в мае у команды не было просадки

Пример паттернов внутри недели:

Понедельник: 0 задач (планирование)
Вторник: 1 задача (разгон)  
Среда: 3 задачи (пик продуктивности)
Четверг: 2 задачи (код-ревью)
Пятница: 2 задачи (релиз)

Интерактивный пример с демо-данными можно посмотреть здесь — как меняются паттерны на масштабе.

Скажу очевидное: Throughput может расти и снижаться. Причины разные: рост команды, декомиссия сервиса, смена продукта или новый тип работы. Для предсказуемости главный аспект — стабильность.

Variance: математический индикатор стабильности

Пример вариативности на неделю 2-8 июня. Команда делает ±104% работы от предыдушего скользящего окна в 4 прошлых периода

Нам нужна команда, по работе которой можно делать прогнозы. Соответственно, для предсказуемости нам важнее смотреть на Коэффициент Вариации. Ведь если скорость скачет — наш прогноз будет ненадёжен.

Variance (коэффициент вариации) = (Стандартное отклонение / Среднее) × 100%

За последние 4–8 периодов. В идеале.

Коэффициент Вариации показывает стабильность throughput:

  • < 15% — очень стабильно
  • 15–30% — достаточно стабильно
  • 30–50% — требует внимания
  • > 50% — критическая нестабильность

То есть в последнем случае, наша команда запилит X задач ±50%. Не очень надёжно.

Примеры разной вариативности: “Американские горки” (Variance 87%)

  • Недели: 15 → 2 → 18 → 1 → 16 задач
  • Признак неконтролируемого процесса.

“Высокая предсказуемость” (Variance 12%)

  • Недели: 7 → 8 → 6 → 7 → 8 задач
  • Хорошая прогнозируемость

Важно: некоторые умные люди считают коэффициент вариации спорным инструментом для Throughput. Распределение Throughput обычно отличается от нормального, поэтому среднее говорит о предсказуемости меньше, чем тренды 50pp / 85pp. Если вы разбираетесь в матстатистике лучше меня, учитывайте этот фактор.

Распределение по типам работы

Типы работы влияют на количество завершённых элементов. Команда может закрыть 4–5 крупных stories или 10–15 небольших багов. Поэтому полезно смотреть на временные тренды Throughput вместе с распределением по типам задач.

Команда начала новый этап работы в Q2 и количество исследовательских задач выросло.

Метрика не говорит что команда “хорошая” или “плохая”

Самое главное — понимать, достигает ли команда поставленных целей. Потому что у вас все метрики могут выглядеть прекрасно и предсказуемо, а делать вы будете не то.

Детский страх почти всех команд и руководителей, как только ты вводишь цели по метрикам

Стабильный или растущий Throughput сам по себе не указывает на положительные или отрицательные характеристики команды. И наоборот, колебания Throughput не обязательно говорят о нестабильности.

Поэтому метрики без балансирующих индикаторов не стоит засовывать в цели команде.

Throughput служит лишь входной точкой для анализа и оптимизации, если возникает такая потребность. Для полноценной оценки важно учитывать также WIP, различные показатели Cycle Time и выходить за рамки процессных метрик — анализировать сбои системы, за которую отвечает команда.

Потому что все метрики связаны законом Литтла.

Закон Литтла — универсальная закономерность в метриках потока

В метриках потока показатели связаны, поэтому смотреть на них нужно вместе. Этот пост сфокусирован на Throughput, без подробного разбора Lead Time и WIP. Работа с одной метрикой меняет остальные. Закон Литтла — фундаментальная теорема теории очередей.

Lead Time = WIP / Throughput

  • WIP — незавершённые задачи в работе одновременно
  • Throughput — количество завершённых элементов
  • Lead Time — время от принятия обязательств до доступности ценности для клиента

Формула закона Литтла для связи WIP, Throughput и Lead Time

Важно: расчёты throughput, анализ потока и симуляции Монте-Карло работают при наличии ограничения на количество одновременно выполняемых задач — WIP-лимита, минимум по верхнему пределу. Без WIP-лимита в работу можно набрасывать бесконечное количество задач, система становится хаотичной, поток трудно анализировать, прогнозы быстро теряют надёжность.

Следующий шаг — прогнозирование

Когда Throughput достаточно стабилен, его можно использовать для вероятностного прогноза.

Хорошая формулировка звучит так: «с 85% вероятностью закончим за 5–7 недель». В ней есть диапазон, вероятность и честное признание неопределённости.

Для этого используется Monte Carlo Simulation: алгоритм много раз собирает будущие сценарии из исторического Throughput команды и показывает распределение вероятных сроков.

Подробную механику, требования к данным, WIP-лимиты и разговор со стейкхолдерами я вынес в отдельную статью: Monte Carlo Simulation: как прогнозировать сроки по Throughput.

Почему Story Points не решают проблем с прогнозируемостью

Давайте обратим, наконец, внимание на слона в комнате — зачем это все надо если есть Story Points?

Дело в том, что SP не имеют корреляции с реальным временем выполнения, так как это относительная величина. То есть 5 SP часто делается за время 2 SP, а задачи, оцененные на 8 SP скачут между абсолютным временем.

Об этом пишет, например University College London (PhD Vali Tawosi, 2023): анализ 500,000+ задач показал отсутствие корреляции между story points и реальным временем разработки. У Daniel Vacanti есть похожий кейс в Siemens.

Пример у Vasco Duarte, по сравнению точности между прогнозами по Story Points и по Work Items. Ссылка на исследование ниже.

Ну и вишенка на торте, у Vasco Duarte — автора NoEstimates, был эксперимент: “Что произойдет с прогнозами, если убрать всю информацию о стори поинтах? Что будет, если все те двойки, тройки, пятерки, восьмерки, тринадцатки превратить в единицы?” — прогнозы с SP отклонились на 20% от финального результата, а по количеству задач — на 4%. Основной вывод — прогнозирование по количеству рабочих элементов дает качество не хуже или лучше, причем требует меньше ресурсов.

SP — классная техника для выравнивания понимания задачи внутри команды на PBR. Для прогнозов лучше подходят метрики потока.

Более того, на опыте больших организаций и финтехов, да и стартапов поменьше, SP обычно использует половина или чуть больше команд. Причем все используют по-разному (если только у них нет хороших Scrum Master / Agile Coach ролей, которых высаживать в каждую команду очень дорого).

В итоге

Мы посмотрели на базовую метрику потока — Throughput, или пропускную способность. Смотреть на неё полезнее в динамике: по значимым периодам времени, типам работы и вариативности.

Метрики нужны не для раздачи ярлыков «хорошая команда» и «плохая команда». Это входная точка для дальнейшего анализа.

На основе этой метрики можно строить вероятностные прогнозы, если система остаётся контролируемой.

Система должна быть контролируемой. Для этого нужен WIP-лимит, минимум по верхней планке. Нет лимита — нет управляемости, нет предсказуемости. Буквальная цитата из книжки:

“No WIP limit = no flow, which means no predictability — don’t bother with Monte Carlo simulations if you don’t control WIP”

Daniel Vacanti

Инструменты визуализации

  • Jira Metrics Plugin — безопасно работающий с данными плагин для хрома. Визуализация Throughput и других метрик прямо в вашей Jira.
  • Predictable Team — stateless анализатор CSV (выгруженных из jira или youtrack). Визуализация Throughput из файла + симуляция Монте-Карло + рекомендации на основе ваших данных.
  • Jira Helper от Паши Ахметчанова. Умеет во много метрик, включая Throughput.
  • TWIG от Actionable Agile. Один из стандартов индустрии: метрики + Монте-Карло. В РФ обычно требует VPN.

Если тема метрик, эффективности команд и применения AI в разработке вас интересует, присоединяйтесь к моему каналу в телеграме: t.me/predictableteam

Python example

Небольшой пример от не-программиста, как построить прогноз если у вас уже есть датасет исторических данных по Throughput.

import random
import numpy as np
from datetime import datetime, timedelta
from typing import List, Tuple

def monte_carlo_when_simulation(
    historical_throughput: List[int],  # Исторические данные пропускной способности (items per week)
    target_items: int,                 # Сколько задач нужно завершить
    simulation_count: int = 5000       # Количество симуляций
) -> dict:
    """
    Monte Carlo симуляция для ответа на вопрос: 
    "Когда мы завершим X задач?"
    
    Возвращает количество недель до завершения
    """
    
    results = []
    
    for _ in range(simulation_count):
        remaining_items = target_items
        weeks_elapsed = 0
        
        while remaining_items > 0:
            # Случайно выбираем пропускную способность из исторических данных
            weekly_throughput = random.choice(historical_throughput)
            
            # Вычитаем завершенные задачи
            remaining_items -= weekly_throughput
            weeks_elapsed += 1
            
            # Защита от бесконечного цикла (если пропускная способность очень низкая)
            if weeks_elapsed > 200:  # ~4 года максимум
                break
        
        results.append(weeks_elapsed)
    
    # Вычисляем статистики
    results.sort()
    
    return {
        'outcomes': results,
        'percentiles': {
            'p50': np.percentile(results, 50),  # 50% вероятность завершить к этому времени
            'p85': np.percentile(results, 85),  # 85% вероятность
            'p95': np.percentile(results, 95),  # 95% вероятность
        },
        'mean': np.mean(results),
        'std_dev': np.std(results),
        'min': min(results),
        'max': max(results)
    }

# Пример использования
if __name__ == "__main__":
    # Исторические данные: сколько задач команда завершала каждую неделю
    historical_throughput = [3, 5, 4, 2, 6, 4, 3, 5, 7, 2, 4, 6, 3, 5, 4, 8, 2, 5, 4, 3]
    
    # Хотим понять: когда завершим 50 задач?
    target_items = 50
    
    # Запускаем симуляцию
    result = monte_carlo_when_simulation(
        historical_throughput=historical_throughput,
        target_items=target_items,
        simulation_count=5000
    )
    
    print(f"Monte Carlo прогноз для завершения {target_items} задач:")
    print(f"50% вероятность завершить за: {result['percentiles']['p50']:.1f} недель")
    print(f"85% вероятность завершить за: {result['percentiles']['p85']:.1f} недель") 
    print(f"95% вероятность завершить за: {result['percentiles']['p95']:.1f} недель")
    print(f"Среднее время: {result['mean']:.1f} недель")
    print(f"Стандартное отклонение: {result['std_dev']:.1f} недель")
    print(f"Диапазон: {result['min']} — {result['max']} недель")
    
    # Конвертируем в календарные даты
    today = datetime.now()
    print(f"\nКалендарные прогнозы (от {today.strftime('%d.%m.%Y')}):")
    print(f"50% уверенности: {(today + timedelta(weeks=result['percentiles']['p50'])).strftime('%d.%m.%Y')}")
    print(f"85% уверенности: {(today + timedelta(weeks=result['percentiles']['p85'])).strftime('%d.%m.%Y')}")
    print(f"95% уверенности: {(today + timedelta(weeks=result['percentiles']['p95'])).strftime('%d.%m.%Y')}")