DORA и метрики инженерной эффективности
Любой руководитель рано или поздно задаёт вопрос: «Мы работаем хорошо или плохо?» Ответ «команда старается» его не устраивает, и тогда рождаются строки кода в неделю, closed story points, процент покрытия тестами и количество коммитов на человека. Все эти числа объединяет одно свойство: они измеряют активность отдельных людей, а не способность организации доставлять ценность. Разница фундаментальная. Активность можно нарастить, не изменив ничего полезного; способность доставлять — нельзя.
DORA (DevOps Research and Assessment) — исследовательская программа, которая с 2014 года пытается ответить на тот же вопрос эмпирически: собрать данные с десятков тысяч инженеров и найти, какие измеримые характеристики процесса доставки статистически связаны с результатами бизнеса. Итог — четыре метрики, которые стали фактическим стандартом отрасли, и модель из двух с лишним десятков практик, которые на эти метрики влияют.
Эта статья — про то, как метрики устроены изнутри: что именно считать, как считать корректно (включая места, где наивный расчёт даёт бессмысленное число), какие выводы из них законны, а какие нет, и почему внедрение DORA чаще всего проваливается не по технической причине.
Предыдущая статья трека — Качество, Definition of Done и релизный менеджмент — описывала, как устроен путь изменения до прода. Здесь мы этот путь измеряем.
Часть 1. Интуиция: почему именно эти четыре числа
Что мы вообще хотим знать
Хорошая метрика системы доставки должна отвечать на два вопроса одновременно:
- Насколько быстро организация превращает решение в работающий у пользователей код?
- Насколько дёшево обходится ошибка на этом пути?
Первый вопрос без второго порождает «ковбоев»: катим по десять раз в день, прод горит. Второй без первого — «осторожных»: релиз раз в квартал после двух недель регресса, зато чисто. Обе крайности — плохие системы, и обе выглядят отлично по одномерной метрике.
Поэтому DORA берёт две оси — пропускную способность (throughput) и стабильность — и на каждой ставит по паре метрик: одну про частоту событий, вторую про длительность.
Ключевая находка: скорость и стабильность не конфликтуют
Управленческая интуиция говорит: чтобы стало надёжнее, надо релизить реже и проверять дольше. Данные DORA говорят обратное. Команды-лидеры показывают одновременно и высокую частоту деплоев, и низкий процент отказов; отстающие — плохи по обеим осям. Корреляция между скоростью и стабильностью в выборке положительная, а не отрицательная.
Механизм понятен, если думать про размер партии. Частый деплой физически означает мелкие изменения: меньше кода за раз → проще ревью → уже область поиска при поломке → дешевле откат → меньше страха → ещё чаще деплой. Это самоусиливающаяся петля, и она же работает в обратную сторону: редкие релизы раздувают партию, партия повышает риск, риск требует ещё более тяжёлой процедуры, процедура делает релизы ещё более редкими.
Квадранты 2 и 4 заселены слабо — это и есть эмпирический результат. Подробный разбор методологии — в книге Николь Форсгрен, Джеза Хамбла и Джина Кима «Accelerate: The Science of Lean Software and DevOps» (IT Revolution, 2018); там же приложение с описанием психометрики, латентных конструктов и кластерного анализа.
Часть 2. Строгие определения
Половина провалов внедрения — это спор «а что считать деплоем». Определения ниже — операционные: их можно превратить в SQL, не додумывая.
Deployment Frequency (DF)
Сколько раз за период изменение кода успешно доехало до продакшена и стало доступно пользователям.
Тонкости:
- Событие — успешный деплой в прод. Провалившиеся выкатки не считаются как деплой (но и не теряются: они попадают в CFR через факт отказа).
- Деплой ≠ релиз. Если вы катите артефакт за feature-flag и включаете фичу через неделю — событием DF считается выкатка артефакта. Про разведение деплоя и релиза — см. Качество и релизный менеджмент.
- Единица измерения — сервис или продукт, а не команда и не монорепозиторий целиком. Сложив деплои сорока микросервисов, вы получите красивое «200 в день» и ноль информации.
- Метрика — счётная и сильно дискретная на низком конце. У команды с релизом раз в две недели «частота» — это фактически бинарный флаг. Поэтому DORA публикует её не как среднее, а как попадание в диапазон.
Lead Time for Changes (LT)
Медиана (или процентиль) времени от первого коммита изменения до момента, когда это изменение работает в проде.
Это не «время от идеи до прода» (то — time to market, оно больше и включает продуктовые очереди) и не cycle time доски Kanban. Граница проведена намеренно: DORA измеряет часть пути, находящуюся под контролем инженерной организации.
Практическая ценность метрики почти целиком в её разложении. Само число «9,5 дня» ничего не подсказывает; разложение показывает, что 75% интервала — это очереди, и что найм «более быстрых программистов» борется за оставшиеся 25%. Про экономику очередей и закон Литтла, который здесь работает буквально, — Kanban и управление потоком.
Change Failure Rate (CFR)
Доля деплоев в прод, которые привели к деградации сервиса и потребовали немедленного вмешательства: отката, хотфикса, патча, форварда-фикса.
$$\mathrm{CFR} = \frac{\text{число деплоев, вызвавших отказ}}{\text{общее число деплоев}}$$
Что не входит: баг, найденный через месяц в редком сценарии; инцидент из-за отказа железа или внешнего провайдера; плановая деградация. Критерий — «изменение сломало то, что работало, и это потребовало срочного действия».
Главная ловушка: знаменатель. Если считать CFR как «инциденты / деплои» и при этом инциденты регистрирует SRE-команда, а деплои считает CI, вы получите число, где числитель и знаменатель живут в разных вселенных. Нужна связка: каждый инцидент должен ссылаться на вызвавший его деплой (или явно помечаться как не связанный с изменением).
Failed Deployment Recovery Time (FDRT)
Сколько времени проходит от начала отказа, вызванного деплоем, до восстановления работы.
В отчётах 2014–2023 годов эта метрика называлась Time to Restore Service и часто по инерции записывалась как MTTR. В отчёте 2024 года DORA переименовала её именно для того, чтобы отвязать от общего MTTR инцидентов: восстановление после собственного плохого деплоя — свойство вашего конвейера (есть ли откат в один клик), а восстановление после падения дата-центра — нет.
О том, почему «MTTR» как среднее — статистически почти бессмысленная величина, отдельный разговор в части 5.
Обратите внимание на окно наблюдения: без него состояние ok недостижимо и CFR невозможно
посчитать за закрытый период. Практика — привязывать окно к скорости обнаружения: если ваш алертинг
ловит регресс за 15 минут, окна в час достаточно; если баг всплывает по ночному батчу — сутки.
Часть 3. Уровни производительности и как их читать
DORA группирует респондентов кластерным анализом в Elite / High / Medium / Low. Ниже — часто цитируемая версия таблицы (по данным отчётов 2019–2021), которую нужно читать с большой осторожностью.
| Метрика | Elite | High | Medium | Low |
|---|---|---|---|---|
| Deployment frequency | по требованию, несколько раз в день | от раза в день до раза в неделю | от раза в неделю до раза в месяц | реже раза в месяц |
| Lead time for changes | менее часа | от дня до недели | от недели до месяца | от месяца до полугода |
| Время восстановления | менее часа | менее дня | менее дня | от недели до месяца |
| Change failure rate | 0–15% | 0–15% | 0–15% | 46–60% |
Четыре предупреждения, без которых таблица приносит вред:
- Границы плавают год от года. Кластеры вычисляются заново на новой выборке, поэтому «Elite» 2019-го и «Elite» 2024-го — разные пороги. Использовать таблицу как список годовых целей («к декабрю выйти в Elite») — ошибка категории.
- Данные самоотчётные. Это опрос: инженеры сами оценивают частоту деплоев по памяти, с добровольной выборкой и понятным перекосом в сторону тех, кому DevOps интересен. Отсюда странности вроде одинакового диапазона CFR у трёх верхних кластеров.
- Связь с бизнесом — корреляционная. Утверждение «software delivery performance предсказывает организационную эффективность» получено на латентных конструктах и опросных данных; это не рандомизированный эксперимент, и причинность из него не следует.
- Elite нужен не всем. Для банковского ядра или прошивки медицинского прибора «несколько деплоев в день» — не цель. Целью остаётся направление движения: короче обратная связь, мельче партия, дешевле откат.
Актуальные отчёты и калькулятор самооценки — на dora.dev, исходные PDF — в разделе dora.dev/research.
Часть 4. Как считать: от событий к числам
Модель данных
Всё сводится к трём таблицам событий. Ключевое проектное решение — связь инцидента с деплоем; без неё CFR и FDRT посчитать честно нельзя.
Источники событий:
DEPLOYMENT— из CI/CD. В GitHub Actions это Deployment API, в GitLab — environments, в Argo CD — события синхронизации. Не выводите деплой из тегов git: теги ставят руками и забывают.CHANGE.first_commit_at— из истории git по коммитам, попавшим в деплой (git log previous_sha..current_sha). Именно первый коммит ветки, не последний: иначе метрика будет игнорировать время, проведённое веткой в ожидании ревью.INCIDENT— из PagerDuty / OpsGenie / Jira. Полеcaused_by_deploy_idзаполняется на разборе инцидента — это ручной шаг, и он неустраним.
Минимальный сбор в CI выглядит так:
# .github/workflows/deploy.yml — фиксация события деплоя после успешной выкатки
- name: Записать событие деплоя
if: success()
run: |
# previous_sha берём из последнего успешного деплоя этого сервиса
PREV=$(curl -sf "$METRICS_API/last-success?service=$SERVICE" | jq -r .commit_sha)
# список коммитов, впервые доехавших до прода этой выкаткой
COMMITS=$(git log --format='%H %aI' "$PREV..${{ github.sha }}")
curl -sf -X POST "$METRICS_API/deployments" \
-H 'content-type: application/json' \
-d "$(jq -n \
--arg svc "$SERVICE" \
--arg sha "${{ github.sha }}" \
--arg at "$(date -u +%FT%TZ)" \
--arg commits "$COMMITS" \
'{service_id:$svc, commit_sha:$sha, deployed_at:$at,
succeeded:true, commits:$commits}')"
Расчёт на Python
"""Расчёт четырёх ключевых метрик DORA из потока событий.
Принципы, заложенные в код:
* никаких средних там, где распределение с тяжёлым хвостом — только процентили;
* период агрегации фиксирован и закрыт (окно наблюдения истекло для всех деплоев);
* метрики считаются на уровне сервиса, а не команды или организации.
"""
from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime, timedelta
from math import ceil
@dataclass(frozen=True)
class Deployment:
deploy_id: str
service_id: str
deployed_at: datetime
first_commit_at: datetime # самый ранний коммит из вошедших в выкатку
succeeded: bool
@dataclass(frozen=True)
class Incident:
incident_id: str
caused_by_deploy_id: str | None
impact_started_at: datetime
resolved_at: datetime | None
def percentile(values: list[float], p: float) -> float:
"""Процентиль методом ближайшего ранга. O(n log n) по времени, O(n) по памяти.
Ближайший ранг выбран сознательно: он возвращает реально наблюдавшееся значение,
а не интерполяцию между двумя измерениями, — так число проще защищать на ревью.
"""
if not values:
raise ValueError("пустая выборка: метрика не определена, а не равна нулю")
ordered = sorted(values)
rank = max(1, ceil(p / 100 * len(ordered)))
return ordered[rank - 1]
def deployment_frequency(deploys: list[Deployment], days: int) -> float:
"""Деплоев в сутки. O(n).
Возвращаем частоту, а не «сколько раз в неделю»: сравнивать периоды разной
длины иначе невозможно. Для отчёта число потом переводят в диапазон DORA.
"""
successful = sum(1 for d in deploys if d.succeeded)
return successful / days
def lead_time_hours(deploys: list[Deployment], p: float = 50) -> float:
"""Процентиль lead time в часах. O(n log n).
Медиана (p=50) отвечает на вопрос «как обычно», p=85 — «что мы можем обещать».
Среднее не используем: одна ветка, провисевшая полгода, сдвинет его целиком.
"""
durations = [
(d.deployed_at - d.first_commit_at).total_seconds() / 3600
for d in deploys
if d.succeeded
]
return percentile(durations, p)
def change_failure_rate(deploys: list[Deployment], incidents: list[Incident]) -> float:
"""Доля деплоев, вызвавших отказ. O(n + m).
Считаем именно ДЕПЛОИ с отказом, а не число инцидентов: один плохой деплой,
породивший три алерта, — это одна неудача, иначе CFR может превысить 100%.
"""
successful = [d for d in deploys if d.succeeded]
if not successful:
raise ValueError("нет успешных деплоев — CFR не определён")
ids = {d.deploy_id for d in successful}
failed_ids = {
i.caused_by_deploy_id
for i in incidents
if i.caused_by_deploy_id in ids
}
return len(failed_ids) / len(successful)
def recovery_times_hours(incidents: list[Incident]) -> list[float]:
"""Длительности восстановления после отказов, вызванных изменением. O(m).
Незакрытые инциденты исключаем — но это цензурирование данных, и оно смещает
оценку вниз. Если незакрытых много, любой процентиль по этой выборке — фикция.
"""
return [
(i.resolved_at - i.impact_started_at).total_seconds() / 3600
for i in incidents
if i.caused_by_deploy_id and i.resolved_at
]
def four_keys(
deploys: list[Deployment],
incidents: list[Incident],
window: timedelta,
) -> dict[str, float | None]:
"""Сводка за окно. Суммарно O(n log n + m)."""
days = window.days
recoveries = recovery_times_hours(incidents)
return {
"deployment_frequency_per_day": deployment_frequency(deploys, days),
"lead_time_p50_hours": lead_time_hours(deploys, 50),
"lead_time_p85_hours": lead_time_hours(deploys, 85),
"change_failure_rate": change_failure_rate(deploys, incidents),
# None вместо нуля: отсутствие отказов — не «мгновенное восстановление»
"recovery_p50_hours": percentile(recoveries, 50) if recoveries else None,
"recovery_sample_size": len(recoveries),
}
Три решения в этом коде стоят отдельного упоминания, потому что именно на них ломаются самодельные дашборды:
recovery_sample_sizeвозвращается вместе с метрикой. Медиана по трём инцидентам — это не медиана, это три числа. Размер выборки должен быть виден на графике всегда.None, а не0, при отсутствии инцидентов. Ноль на дашборде читается как «восстанавливаемся мгновенно» и попадает в усреднение по организации, занижая всё вокруг.- Исключение — а не подмена нулём — незакрытых инцидентов. Это классическое цензурирование справа: активные, самые долгие инциденты систематически выпадают из выборки.
То же самое на SQL
-- Четыре ключевые метрики за 90 дней, по сервисам.
-- Окно наблюдения (24 ч) вычтено, чтобы не считать деплои, чей исход ещё неизвестен.
WITH win AS (
SELECT now() - interval '90 days' AS from_ts,
now() - interval '24 hours' AS to_ts
),
deploys AS (
SELECT d.service_id,
d.deploy_id,
d.deployed_at,
-- начало lead time: самый ранний коммит, впервые доехавший этой выкаткой
MIN(c.first_commit_at) AS started_at
FROM deployment d
JOIN change c ON c.deploy_id = d.deploy_id
CROSS JOIN win
WHERE d.succeeded
AND d.deployed_at BETWEEN win.from_ts AND win.to_ts
GROUP BY d.service_id, d.deploy_id, d.deployed_at
),
failed AS (
SELECT DISTINCT caused_by_deploy_id AS deploy_id
FROM incident
WHERE caused_by_deploy_id IS NOT NULL
)
SELECT
d.service_id,
COUNT(*) / 90.0 AS deploys_per_day,
PERCENTILE_CONT(0.50) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM d.deployed_at - d.started_at) / 3600
) AS lead_time_p50_h,
PERCENTILE_CONT(0.85) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM d.deployed_at - d.started_at) / 3600
) AS lead_time_p85_h,
COUNT(f.deploy_id)::numeric / COUNT(*) AS change_failure_rate,
COUNT(*) AS sample_size
FROM deploys d
LEFT JOIN failed f USING (deploy_id)
GROUP BY d.service_id
HAVING COUNT(*) >= 10 -- меньше десяти деплоев: показывать метрику нечестно
ORDER BY lead_time_p50_h DESC;
Готовая референсная реализация от Google Cloud — открытый проект dora-team/fourkeys: парсеры вебхуков GitHub/GitLab, BigQuery-схема и дашборд. Читать его полезно даже если брать не будете — там аккуратно решены именно вопросы связывания событий.
Часть 5. Статистика, о которой обычно молчат
Почему среднее время восстановления бесполезно
Длительности инцидентов распределены с очень тяжёлым хвостом: большинство чинится за минуты, единицы тянутся часами. У таких распределений выборочное среднее нестабильно — оно скачет от единичных наблюдений, — а квартальных инцидентов у команды обычно 5–20 штук.
Штепан Давидович в работе Google «Incident Metrics in SRE: Critically Evaluating MTTR and Friends» проделал прямой эксперимент: сгенерировал две популяции инцидентов, одна из которых по построению на 10% лучше другой, и проверил, отличит ли их MTTR на реалистичных объёмах данных. Результат: при типичном числе инцидентов улучшение неотличимо от шума; чтобы уверенно поймать разницу, нужны сотни наблюдений. Практические выводы:
- Не ставьте цель «снизить MTTR на 20% за квартал» — вы не сможете доказать, что достигли её.
- Смотрите на распределение целиком (диаграмма разброса длительностей), а не на одну цифру.
- Считайте более грубые, но устойчивые вещи: доля инцидентов дольше часа, число инцидентов, доля восстановлений через автоматический откат.
Та же логика применима к lead time и вообще ко всему в этой статье: работайте с процентилями и показывайте размер выборки. Техника та же, что для cycle time в Kanban.
Сколько данных нужно, чтобы заметить изменение
Простая прикидка через бутстрап, которая экономит квартал бессмысленных споров на ретро:
import random
import statistics
def bootstrap_ci(sample: list[float], p: float = 50,
iterations: int = 10_000, alpha: float = 0.05
) -> tuple[float, float]:
"""Доверительный интервал для процентиля методом бутстрапа.
Время: O(iterations * n log n). Память: O(iterations).
Практический смысл: если интервалы двух кварталов пересекаются,
заявлять об улучшении нельзя — как бы ни хотелось на демо.
"""
n = len(sample)
estimates = []
for _ in range(iterations):
resample = [random.choice(sample) for _ in range(n)]
resample.sort()
idx = max(0, round(p / 100 * n) - 1)
estimates.append(resample[idx])
estimates.sort()
lo = estimates[int(alpha / 2 * iterations)]
hi = estimates[int((1 - alpha / 2) * iterations)]
return lo, hi
# Типичный результат для 12 инцидентов за квартал:
# медиана 42 мин, интервал [18, 130] — то есть «стало лучше на 15%» недоказуемо.
incidents_minutes = [12, 18, 25, 31, 38, 42, 47, 61, 95, 130, 210, 480]
print(statistics.median(incidents_minutes), bootstrap_ci(incidents_minutes))
Часть 6. Как метрики ломаются: закон Гудхарта в действии
«Когда мера становится целью, она перестаёт быть хорошей мерой». Формулировка Мэрилин Стратерн по мотивам Чарльза Гудхарта.
Метрики DORA спроектированы как диагностические, но их постоянно назначают целевыми — и каждая из них ломается предсказуемым способом.
| Метрика | Как её накручивают | Что видно в системе |
|---|---|---|
| Deployment frequency | пустые деплои, разбиение одного изменения на пять выкаток, no-op пайплайны | растёт DF при неизменном lead time и объёме изменений |
| Lead time | коммит делается перед самым мерджем; долгоживущая ветка «переоткрывается» | p50 падает, p85 и p95 стоят на месте |
| Change failure rate | инцидент не заводят, а «правят по-тихому»; понижают серьёзность | CFR падает вместе с числом заведённых инцидентов |
| Recovery time | таймер инцидента стартует в момент, когда починка уже почти готова | сокращается время, но растёт разрыв между началом воздействия и заведением |
Отсюда два практических правила.
Правило первое: никогда не сравнивайте команды по DORA. Метрики зависят от домена (платёжное ядро против внутреннего дашборда), архитектуры (монолит против сервисов) и регуляторики. Сравнение команд между собой создаёт стимул оптимизировать число, а не систему. Легитимное сравнение только одно — команда с собой во времени.
Правило второе: DORA не входит в оценку людей. Как только метрика попадает в перформанс-ревью или в бонус, качество данных умирает: инциденты перестают заводить, деплои начинают дробить. Обсуждение того, почему индивидуальные метрики производительности не работают в разработке, см. в ответе Кента Бека и Гергея Ороша на нашумевший материал McKinsey — «Measuring developer productivity? A response to McKinsey». Про мотивацию и то, что происходит с командой под измерением, — в статье Команда, коммуникации, конфликты и мотивация.
Ещё три типичные ошибки внедрения:
- Метрики без capability-модели. Четыре числа — это термометр. Лечат не термометром: в модели DORA есть более двух десятков практик-предикторов (транковая разработка, непрерывное тестирование, слабосвязанная архитектура, автоматизация деплоя, наблюдаемость, генеративная культура по типологии Уэструма). Улучшение метрик — следствие внедрения практик, а не самостоятельное действие.
- Агрегация по организации. Средний lead time по сорока командам — число, которое не может ни вырасти, ни упасть осмысленно. Агрегировать можно распределение («доля сервисов с p85 < 1 дня»), но не сами длительности.
- Дашборд вместо разговора. Метрика полезна ровно в тот момент, когда команда смотрит на неё и спрашивает «почему?». Панель, на которую никто не смотрит на ретро, — это затраты без эффекта.
На этой схеме: lead time — интервал B → H, deployment frequency считает события G, CFR — доля G, из которых есть переход в I, FDRT — длительность петли I → G. Всё, что слева от B, в метрики DORA не входит — и это регулярный источник спора с продуктом, который справедливо считает свои очереди частью срока.
Часть 7. За пределами четырёх метрик
DORA измеряет систему доставки. Она принципиально ничего не говорит о том, делаете ли вы нужный продукт и в каком состоянии находятся люди. Закрывать эти пробелы призваны два более поздних фреймворка.
SPACE
«The SPACE of Developer Productivity» (Форсгрен, Стори, Маддила, Циммерманн, Хоук, Батлер; ACM Queue, 2021) утверждает, что продуктивность многомерна, и предлагает пять измерений:
- Satisfaction and well-being — удовлетворённость, выгорание;
- Performance — результат (не активность): надёжность, влияние на пользователя;
- Activity — счётчики: коммиты, PR, деплои;
- Communication and collaboration — скорость ревью, качество документации, «bus factor»;
- Efficiency and flow — прерывания, время в потоке, длина очередей.
Главная рекомендация статьи операционна: брать метрики минимум из трёх измерений и обязательно включать хотя бы одну перцептивную (то есть из опроса). Комбинация «Activity в одиночку» — ровно тот антипаттерн, с которого начиналась эта статья.
DevEx
«DevEx: What Actually Drives Productivity» (Нода, Стори, Форсгрен, Грайлер; ACM Queue, 2023) идёт дальше и описывает три фактора разработческого опыта:
- петли обратной связи — сколько ждать ответа от системы (сборка, тесты, ревью, деплой);
- когнитивная нагрузка — сколько нужно держать в голове, чтобы внести изменение;
- состояние потока — как часто удаётся работать без прерываний.
Это самый практичный из трёх фреймворков для конкретных инженерных решений: он прямо указывает, что сокращение сборки с 20 до 4 минут — не «инфраструктурная задача низкого приоритета», а изменение петли обратной связи с измеримым эффектом.
Практический синтез, который работает у большинства команд: DORA + одна перцептивная метрика + одна продуктовая. Например: четыре ключевые метрики с дашборда CI, ежеквартальный короткий опрос о трении в разработке (5–7 вопросов) и одна метрика влияния на пользователя. Три источника разной природы дают триангуляцию, которую невозможно накрутить с одной стороны.
Часть 8. Как внедрять: порядок шагов
- Начните с одного сервиса и одной команды. Не с организации. Цель первого месяца — не улучшить метрики, а получить данные, которым команда верит.
- Автоматизируйте сбор деплоев и коммитов, инциденты размечайте руками. Автоматическая привязка инцидента к деплою — заманчивая, но почти всегда ошибочная идея: причинность устанавливает человек на разборе.
- Покажите распределения, а не одно число. Диаграмма разброса lead time с линиями p50/p85 — более полезный артефакт, чем большая цифра на дашборде.
- Смотрите метрики на ретроспективе, а не на статус-встрече с руководством. Вопрос, который надо задавать: «что в этом квартале было самой длинной очередью и что мы с ней сделаем?»
- Выберите одну capability на квартал. Например: сократить время сборки вдвое; ввести транковую разработку; сделать откат в один клик. Метрика — способ проверить гипотезу, а не сама работа.
- Явно зафиксируйте, что метрики не используются для оценки людей — и соблюдайте это. Один нарушенный случай стоит года доверия к данным.
Полезный стартовый инструмент — DORA Quick Check: короткая самооценка, которая ставит команду относительно выборки и подсказывает, какие практики подтягивать.
Отдельное замечание про 2024–2025 годы: отчёты DORA зафиксировали, что рост внедрения ИИ-ассистентов увеличивает объём и скорость производимых изменений, но сам по себе не улучшает стабильность доставки — узкое место просто смещается ниже по конвейеру (ревью, тестирование, выкатка). Это ровно тот случай, когда метрики полезны: они показывают, где именно образовалась новая очередь, вместо общего ощущения «стало быстрее».
Мини-итог
- Четыре ключевые метрики — это 2×2: скорость и стабильность, каждая как частота событий и как длительность. Смотреть их поодиночке нельзя: пары уравновешивают друг друга.
- Определения должны быть операционными до уровня SQL. Самый тонкий момент — связь инцидента с деплоем; без неё CFR и время восстановления не считаются честно.
- Всегда процентили, никогда среднее; всегда с размером выборки. MTTR по десятку инцидентов статистически неотличим от шума — цели на его снижение недостижимы в принципе.
- Скорость и стабильность в данных положительно коррелируют. Механизм — размер партии.
- Уровни Elite/High/Medium/Low — описание выборки конкретного года, а не список целей.
- Метрики диагностические, а не целевые. В перформанс-ревью они попадать не должны — иначе данные испортятся быстрее, чем улучшится процесс.
- DORA не покрывает людей и продукт: дополняйте перцептивной метрикой (SPACE, DevEx) и хотя бы одной продуктовой.
Источники
- Nicole Forsgren, Jez Humble, Gene Kim. Accelerate: The Science of Lean Software and DevOps — itrevolution.com/product/accelerate
- DORA — исследования и отчёты State of DevOps — dora.dev/research
- DORA. Руководство по четырём ключевым метрикам — dora.dev/guides/dora-metrics-four-keys
- DORA Core: capability-модель — dora.dev/capabilities
- Google Cloud. Four Keys (открытая референсная реализация) — github.com/dora-team/fourkeys
- Štěpán Davidovič. Incident Metrics in SRE: Critically Evaluating MTTR and Friends — sre.google/resources/practices-and-processes/incident-metrics-in-sre
- Forsgren et al. The SPACE of Developer Productivity. ACM Queue, 2021 — queue.acm.org/detail.cfm?id=3454124
- Noda, Storey, Forsgren, Greiler. DevEx: What Actually Drives Productivity. ACM Queue, 2023 — queue.acm.org/detail.cfm?id=3595878
- Jez Humble, David Farley. Continuous Delivery — continuousdelivery.com
- Martin Fowler. Trunk Based Development / Feature Toggles — martinfowler.com/articles/feature-toggles.html
- Kent Beck, Gergely Orosz. Measuring developer productivity? A response to McKinsey — newsletter.pragmaticengineer.com
- Ron Westrum. A typology of organisational cultures. BMJ Quality & Safety, 2004 — doi:10.1136/qshc.2003.009522
- Google SRE Workbook, «Implementing SLOs» — sre.google/workbook/implementing-slos
Что дальше
Мы научились измерять систему доставки одной команды и увидели, что почти все ответы прячутся в очередях между этапами. Когда команд становится не одна, а тридцать, очереди возникают уже между командами — и отрасль отвечает на это готовыми фреймворками масштабирования, у каждого из которых своя цена. Об этом — следующая статья:
Масштабирование процессов: SAFe, LeSS, Spotify-модель и их критика
Если нужен фундамент по потоку и процентилям, на котором стоит вся эта статья — см. Kanban и управление потоком; про релизный конвейер и Definition of Done — Качество, Definition of Done и релизный менеджмент; общая карта трека — Управление проектами в IT.