Перейти к содержимому

«99.9% потому что круто» — типичная цель по SLO, которую я регулярно вижу. Каждая следующая девятка стоит на порядок дороже: переход 99% → 99.9% → 99.99% меняет и стоимость инфраструктуры, и требования к команде, и частоту, с которой люди просыпаются ночью. Без обоснования через боль пользователя это просто магическое число. Защищать его на ревью бюджета никто не станет. Этот лист про инженерную сторону: как из бизнес-сигнала вывести SLI, как сформулировать SLO, как всё это инструментировать. Не путать с SLO / Budget Review (ритуал ревью) и SLI-based Alerting (алерты поверх SLO).

Главный навык на уровне L4 — записывать SLI как отношение good events / valid events и обосновывать выбор знаменателя. Знаменатель решает, про что SLO; неаккуратный знаменатель, куда попали проверки живости, боты и внутренние пробы мониторинга, делает SLO бессмысленным. Я регулярно вижу команды, которые часами обсуждают числитель и решают судьбу знаменателя за пять минут. Порядок перевёрнут.

L3

  • Различает SLI / SLO / SLA. Читает чужие SLO-описания и понимает, что они формализуют.
  • Читает существующие SLO своей команды; в инциденте может сказать, какие SLO под угрозой и сколько бюджета осталось.

L4

  • Записывает SLI как отношение good events / valid events. Обосновывает выбор знаменателя в SLO-документе сервиса.
  • Определяет простой SLO для одного сервиса — по доступности, по задержке или по обоим сразу; выбирает окно — скользящие 28 дней или календарный месяц — и обосновывает выбор.
  • Ставит первую цель от фактического уровня сервиса за последний квартал, а не от красивого числа; записывает, по какому поводу цель пересматривается.

L5

  • Проектирует набор SLI для сервиса: для онлайн-сервиса — RED (поток, ошибки, длительность); для пакетной обработки — свежесть данных, пропускная способность, корректность; для пользовательского сценария — составной индикатор по всему пути.
  • Инструментирует сервис: где возможно — со стороны клиента (синтетика, телеметрия из браузеров), на сервере — через клиент Prometheus или SDK OpenTelemetry; пишет правила агрегации (recording rules) по разным окнам.
  • Декомпозирует составной запрос на компонентные SLI и понимает, какой SLI ловит какую часть деградации.
  • Выделяет критичные пользовательские пути (critical user journey, CUJ) и проверяет экспериментом, отказ каких вызовов путь ломает, а какие пользователь переживёт.
  • Для сервиса с плавной деградацией добавляет индикатор качества ответа (quality SLI): долю ответов, отданных без урезания.
  • Проверяет индикатор на подгонку до внедрения: отвечает на вопрос, как улучшить число, не улучшая сервис, и закрывает найденное вторым индикатором на тот же путь или записанным списком исключений.

L6+

  • Внедряет инфраструктуру SLO в команде: правила агрегации, дашборды скорости сжигания, расчёт бюджета ошибок как код (Sloth, Pyrra, Nobl9), записанная политика бюджета.
  • Согласует цель с ожиданиями бизнеса: 99.99% против 99.9% — это разница в деньгах; обосновывает выбор через боль пользователя и стоимость, а не «99.9%, потому что круто».
  • Сверяет записанную цель с фактическим уровнем в обе стороны: сервис, который год держит на девятку больше обещанного, живёт с неявным SLO (implicit SLO), и потребители считают по нему.
  • Меняет определение SLI без разрыва истории: исправленный индикатор заводится рядом со старым, переход идёт с объявленной датой.

Разговор про цель идёт в процентах, а живёт команда в минутах. Перевод одного в другое стоит держать под рукой — допустимое время простоя для каждой девятки:

Доступность Простой в год Простой в месяц (30 суток) Простой в неделю
90% 36.5 суток 72 часа 16.8 часа
99% 3.65 суток 7.2 часа 1.68 часа
99.9% 8.76 часа 43.2 минуты 10.1 минуты
99.99% 52.6 минуты 4.32 минуты 1.01 минуты
99.999% 5.26 минуты 25.9 секунды 6.05 секунды
99.9999% 31.5 секунды 2.59 секунды 0.6 секунды

Таблица посчитана для календарных окон: год — 365 суток, месяц — 30. Если SLO записан на скользящем окне в 28 дней, а так чаще и бывает, бюджет примерно на 7% меньше месячного из таблицы: для 99.9% это 40.3 минуты вместо 43.2. Считать нужно в том окне, в котором записан SLO, иначе burn rate на дашборде и цифра в SLO-документе разойдутся.

Практический смысл этих чисел виден на границе 99.99%: месячный бюджет — 4.32 минуты, а типичный путь «алерт → дежурный проснулся → понял → откатил» занимает больше. То есть цель выше трёх девяток — это уже не про дисциплину дежурных, а про автоматический failover и rollback без человека в цикле. Я регулярно вижу, как команда соглашается на 99.99% в SLA с клиентом, не имея ни того, ни другого.

  • Alex Hidalgo — Implementing Service Level Objectives (O’Reilly, 2020). Рекомендую как главный практический источник: главы с первой по шестую ведут от определения SLI до расчёта бюджета ошибок.
  • Betsy Beyer et al. — The Site Reliability Workbook (O’Reilly, 2018), глава 2 «Implementing SLOs». Тоже рекомендую: канонический подход Google, короче и суше Идальго.
  • Betsy Beyer et al. — Site Reliability Engineering (O’Reilly, 2016), глава 4 «Service Level Objectives». Рекомендую как фундамент: база терминологии и модели, на которых стоит всё остальное. За устройством практики идти не сюда.
  • Betsy Beyer et al. — Alerting on SLOs (SRE Workbook, гл. 5). Связь инженерной части SLO со стратегией алертинга. Рекомендую прочитать до того, как настраивать алерты, иначе они встают на метрики, а не на бюджет.
  • Betsy Beyer et al. — Appendix B. Example Error Budget Policy (SRE Workbook). Готовый шаблон Error Budget Policy. Рекомендую начинать с него, а не писать политику с нуля.
  • Štěpán Davidovič — Measuring Reliability: What Got Us Here Won’t Get Us There (SREcon22 EMEA). Про то, где привычный способ измерять надёжность перестаёт работать. Сам не смотрел; в списке доклад стоит как единственный источник, который с остальными спорит, а не достраивает их.
  • Niall Murphy — Implicit SLOs and their dangers (blog.relyabilit.ie, октябрь 2024). Короткий текст о том, что привычный потребителям уровень работает как SLO независимо от записанного. Рекомендую читать в паре с врезкой про Chubby из главы 4 SRE Book: там случай, здесь выводы из него.
  • Александр Попов — Как приручить SLO’на в племени микросервисов (блог Dodo Engineering на Хабре, декабрь 2025). Второй заход на SLO в компании с сотнями микросервисов и список того, что не сработало в первом. Беру отсюда две вещи: доступность снимают с ингресса, а не с самого сервиса, и завышенные цели корректируют вниз без драмы.
  • yakenji (Mercari SRE) — Keeping User Journey SLOs Up-to-Date with E2E Testing in a Microservices Architecture (Mercari Engineering, декабрь 2024). Рекомендую ради двух вещей: способа найти критичные API внедрением отказов и списка ограничений в конце. Вторая половина — про то, как держать перечень критичных вызовов актуальным через E2E-тесты.
  • Мой разбор — SLO как чертёж архитектуры (jtprog.ru, май 2026). Прохожу цепочку целиком на одном кейсе поиска в маркетплейсе: функциональные требования → критичный пользовательский путь → шаги пути → SLI → SLO → бюджет ошибок. Источники выше начинают сразу с индикатора; здесь начало на шаг раньше, потому что, по моим наблюдениям, спорят в командах про сценарий, а не про формулу. Отдельным разделом — что в SLI брать нельзя.
  • Мой разбор — Изменил формулу SLI — и сломал историю (Telegram, апрель 2026). Короткий пост про то, почему правка формулы создаёт новое измерение, а не чинит старое, и чем её заменить. Писал его после DevOpsConf 2026, где этот тезис у меня и сложился.
  • Мой разбор — Закон Гудхарта и токсичные SLO: как не убить надёжность метриками (Telegram, февраль 2026). Короткий пост про то, что делают с SLI, когда от него зависят премии и OKR. В книгах выше на эту тему одна фраза в Workbook; у меня — список приёмов подгонки и то, чем их закрывают.
  • Prometheus — recording rules для SLI, правила алертинга для скорости сжигания. Канонический стек, рекомендую начинать с него: остальное в этом ряду так или иначе описывает то же самое.
  • Sloth — генератор PromQL для SLO и burn-rate алертов из декларативного YAML. По моим наблюдениям, чаще выбирают в командах от 5+ сервисов.
  • Pyrra — открытая платформа управления SLO поверх Prometheus: дашборд бюджета ошибок, многооконные алерты, оператор для Kubernetes.
  • OpenSLO — независимая от вендоров спецификация SLO в YAML; утилита oslo проверяет их прямо в конвейере. Рекомендую как формат описания, даже если платформа потом сменится.
  • Nobl9 — коммерческая платформа поверх любого мониторинга. Сам не работал; коллеги рекомендуют её там, где SLO надо держать в едином виде сразу по многим командам.
  • SLO-документ — заготовка документа на один сервис из этого репозитория: SLI с явным знаменателем, цель с обоснованием, окно, бюджет ошибок, исключения и порядок пересмотра. Форма для того, что выше названо «SLO-документом сервиса».
  • Error Budget Policy — заготовка политики бюджета ошибок: пороги расхода, действие на каждом, условия заморозки и выхода из неё. Парный документ к предыдущему: тот записывает цель, этот — что происходит, когда она нарушена.

Начну с того, что чаще всего ломает SLO ещё до первого дашборда: знаменатель важнее числителя. Good events обсуждают часами, valid events не обсуждает никто. Не отфильтруешь ботов, проверки живости, заведомо кривых клиентов и операции в окне обслуживания — получишь SLO, который либо не нарушается никогда, потому что технический шум разбавляет любую деградацию, либо нарушается постоянно, потому что в знаменатель попал трафик, за который ваш сервис вообще не отвечает. Ревью по такому индикатору бессмысленно в обоих случаях.

Второе — начинать с одного SLI на один сервис. Заход «покроем всё сразу, пятьдесят индикаторов на пятьдесят ручек» заканчивается тем, что в них никто не разбирается, а ревью превращается в чтение портянок. Запустите один корректный SLI, проведите его через первый SLO Review, отшлифуйте процесс. Потом расширяйте.

Третье касается самого числа. Цель выводится из боли пользователя, а не из красоты цифры: при каком уровне SLI человек начинает жаловаться, уходить или терять деньги — это и есть ваше число. Каждая девятка сверху стоит на порядок дороже, и платить эту цену без ответа на вопрос «кому и когда стало плохо» — чистое расточительство.

Когда про боль пользователя спросить некого, а на первом заходе так обычно и бывает, число берётся из истории самого сервиса: что он фактически выдавал за последний квартал, с небольшим запасом вниз. Канон тут спорит сам с собой. В SRE Book советуют не выбирать цель по текущим показателям, чтобы не закрепить уровень, который держится на героизме. В Workbook совет смягчают: текущий уровень годится как отправная точка, когда другой информации нет и налажен пересмотр. Мне ближе второе, и причина арифметическая. Сервис квартал выдавал 99.7%, в SLO-документ записали 99.95% — бюджет ошибок сгорел в день внедрения. Дальше команда либо живёт в вечной заморозке релизов, либо перестаёт на SLO смотреть.

Ужесточается такая цель по поводу, а не по календарю. Поводов я знаю три: бюджет несколько окон подряд остаётся недожжённым, под конкретную цифру сделано вложение в надёжность, бизнес прямо просит более жёсткое обещание. Обратное движение тоже законно. В Dodo Engineering нескольким маршрутам сервиса меню поставили слишком оптимистичные цели по времени ответа, получили просадку в метриках и пороги скорректировали. Вывод оттуда стоит держать перед глазами: «корректировка показателей — это не про уступки, а про баланс».

А 100% не цель вообще. В Workbook довод простой: даже если довести до ста процентов собственную систему, пользователь их не увидит, потому что между ним и сервисом длинная цепочка чужих систем и отказать может любая. Бюджет при такой цели нулевой. Любое изменение становится риском, на который нет права, и сервис перестаёт развиваться.

У сервиса есть SLO, даже если его никто не записал. Niall Murphy называет это неявным SLO: исторический уровень, к которому потребители привыкли и вокруг которого построили свои кеши, обработку ошибок и повторы. Следствий два. Приятное: если первая записанная цель совпала с неявной, никто ничего не заметит, и это ещё один довод брать число из истории. Неприятное: фактическую надёжность опасно менять в обе стороны. Стало хуже — потребителям срочно достраивать защиту. Стало заметно лучше — построенная защита простаивает, а те, кто её не строил, начинают грузить сервис сильнее прежнего.

Хрестоматийный случай описан в SRE Book. Глобальный Chubby, сервис блокировок Google, отказывал так редко, что владельцы сервисов стали завязываться на него как на то, что не падает никогда, и каждый настоящий его сбой оборачивался отказами у них. Ответ SRE звучит дико, пока не дочитаешь до обоснования: Chubby держали на уровне SLO, но не заметно выше. Если за квартал настоящий сбой не ронял доступность ниже цели, систему намеренно клали управляемым отключением. Необоснованные зависимости так всплывали вскоре после появления, а не в день большой аварии.

Murphy выводит отсюда следствие из закона Хайрама (Hyrum’s Law) и приписывает его Идальго: уровень надёжности — такое же наблюдаемое поведение системы, как формат ответа, и на него точно так же кто-нибудь завяжется. Для SLO-документа это означает сверку в обе стороны. Сервис, который год держит 99.99% при записанных 99.9%, потребители считают сервисом на 99.99%, и записанная цифра его владельца не защитит. По-моему, сами управляемые отключения остаются приёмом для внутренней платформы с десятками потребителей, и в SRE Book оговорка про инфраструктурные сервисы стоит прямо в тексте. Внешнему клиенту намеренный простой не объяснишь, там остаётся предупреждать заранее.

SLI считается на стороне клиента, когда это возможно. Одни только серверные метрики ничего не знают про DNS, балансировщик, деградацию сети и сорванное рукопожатие TLS. Синтетические проверки из сторонних регионов и телеметрия с реальных клиентов стоят ближе к пользовательскому опыту, а серверные метрики их дополняют, но не заменяют. Я регулярно вижу команды, у которых серверный SLI зелёный, а NPS едет вниз. Это ровно та слепота, о которой речь.

SLI на пользовательский сценарий, а не на отдельную ручку. Индикатор на каждый HTTP-маршрут нечитаем и о пользовательском опыте говорит мало. Пользователь не знает про ручки, он знает про действие: оплата прошла, поиск работает. В Workbook такое действие называют критичным пользовательским путём, CUJ. Значит, и SLI собирается составным, по всему сценарию — из метрик всех компонентов, через которые проходит запрос от нажатия кнопки до ответа, включая те, что живут в чужих командах и про ваш SLO ничего не знают. Делать это сложнее. Зато это единственный способ разговаривать про SLO с продуктовой командой на одном языке.

Как это выглядит на масштабе, в декабре 2024 описала SRE-команда Mercari. Команды сервисов там ведут свои SLO, и в статье прямо сказано, чем этого мало: сервисы A, B и C могут уложиться в цели каждый по отдельности, а доступность глазами пользователя окажется ниже, и алерт сервиса A не говорит, кого задело. SRE смотрели на маркетплейс через CUJ и раньше, но на один путь приходилось несколько SLO, по одному на связанный API, а определения путей нигде не были записаны. Их определили заново, около сорока: выставить товар, купить, найти. Каждый описан диаграммой переходов между экранами и привязан к одному SLI доступности и одному SLI задержки.

Самое полезное в статье — способ искать критичные вызовы. Между сборкой приложения для разработки и стендом поставили mitmproxy, заставляли отдельные API отвечать ошибкой 500 и проходили путь заново. Путь развалился — вызов критичный и входит в SLI. Не развалился — второстепенный, как подсказки. Оговорки выписаны там же, и прочитать их стоит до того, как повторять: переходы между экранами напрямую не измеряются и API служат заменителем, критичные вызовы определяли только на iOS, а новые SLO на момент публикации обкатывались внутри SRE-команды.

С составным SLO осторожнее: формула не очевидна. Записать «SLO — это произведение компонентных SLO» в лоб — антипаттерн. Настоящая формула зависит от того, последовательно или параллельно используются компоненты, насколько они коррелированы и есть ли между ними повторы. Считается такое либо симуляцией, либо явным разбором зависимостей. Услышали в команде «давай просто перемножим» — копайте глубже. У Mercari доступность пути посчитана как раз произведением успешности критичных API, а достижение цели по задержке взято по худшему из них. Противоречия нет: перемножали после того, как экспериментом выяснили, какие вызовы стоят в пути без запасного хода. Независимость отказов в такой формуле остаётся допущением, и в статье оно не обсуждается.

Отдельного индикатора заслуживает деградация. Сервис, который умеет отвечать урезанно — рекомендации из кеша вместо персональных, страница без блока отзывов, — по SLI доступности выглядит здоровым: код 200, запрос успешен. В Workbook рядом с доступностью и задержкой для такого случая стоит третий тип индикатора, quality: доля ответов, отданных без деградации. Пример оттуда же — игра, в которую при недоступном хранилище пользовательских данных по-прежнему можно играть, только с типовыми картинками.

Считается он от счётчика, который сервис увеличивает в момент выбора запасного пути, а не по факту ошибки. Чтобы из счётчика получилась доля, штатные ответы тоже приходится считать: снова знаменатель. У индикатора два слепых места, и оба стоит записать прямо в SLO-документ. Он видит только ту деградацию, о которой сервис сообщил сам: устаревший кеш, отданный как свежий, счётчик не тронет. И без веса он складывает несравнимое: потерянный блок рекомендаций и потерянная корзина дают одинаковый плюс один. Разбивка по критичности — тема листа Resilience Patterns, и раньше, чем в сервисе появилась явная плавная деградация, заводить quality SLI незачем: считать будет нечего.

Предпоследнее — про индикатор через полгода, когда выясняется, что формула кривая. Рука тянется поправить запрос в правиле агрегации. По-моему, это ошибка серьёзнее той, которую исправляют. После правки ряд до и после описывает разные вещи, а бюджет ошибок считается нарастающим итогом по окну: он либо обнуляется, либо выглядит бесконечным, хотя надёжность сервиса не изменилась. Рабочий путь другой: исправленный индикатор заводится рядом, под новым именем, а старый продолжает считаться ещё одно-два окна.

Форма для этого есть в Workbook, хотя описана она для другого случая: нужна цель жёстче, а продукт до неё пока не дотягивает. Называется aspirational SLO. Цель измеряют и показывают рядом с действующей, а в политике бюджета прямо записано, что действий она не требует. На новый индикатор механика переносится без изменений. С порогом проще: новый порог можно приложить к историческим данным SLI и посмотреть, какие события он поймал бы. С формулой так выходит не всегда: пересчитать её назад можно, только пока хранятся сырые данные. И ещё про слова: не «мы ошиблись», а «мы нашли более точный способ измерять надёжность». После второй фразы никто не ищет виноватого.

Последнее — про то, что делается с индикатором, когда его выполнение превращают в оценку. В Workbook есть фраза, которую легко проскочить. Перед ней перечислены четыре условия: цель одобрили все, кого она касается; ответственные за сервис согласны, что в обычных условиях она достижима; организация обязалась принимать решения по бюджету ошибок и записала это в политику; есть порядок пересмотра цели. Без них, сказано там, выполнение SLO останется ещё одним KPI или строкой отчётности, а инструментом принятия решений не станет. В Workbook речь о цифре, по которой никто ничего не решает. Хуже, когда по ней начинают решать про людей: премия, грейд, строка в OKR команды. Это я считаю одной из самых дорогих ошибок в теме.

Механизм описывает закон Гудхарта: когда мера становится целью, она перестаёт быть хорошей мерой. Пока по SLI решают судьбу сервиса, команде выгодно, чтобы он показывал правду. Когда от него зависит премия, выгодной становится красивая цифра, и получить её проще всего, не трогая сервис. Способы перечислю, потому что почти все они лежат в инженерной части. В знаменателе остаются проверки живости, которые разбавляют любую деградацию: выше это описано как небрежность, здесь то же делают намеренно. Неудобные запросы из него, наоборот, пропадают как «не наш трафик». Порог задержки переезжает туда, где его никто не задевает. Цель записывается с запасом, который не сгорит никогда. А разбор сбоя начинается со спора, считать ли его инцидентом. Сам сервис остаётся каким был. На дашборде 99.95%, пользователям плохо, и одно другому не мешает.

Защита закладывается при проектировании, и начинается она с вопроса про каждый новый SLI: как улучшить это число, не улучшая сервис? Найденные ответы закрываются тем, что в листе уже есть. Измерение со стороны клиента подправить труднее, чем серверный счётчик: оно снимается там, куда команда сервиса не дотягивается. Два-три независимых индикатора на один путь подделать сложнее, чем один, потому что они тянут в разные стороны. Обрезал долгие запросы по таймауту — задержка похорошела, доступность просела. Отдал заглушку вместо ответа — просел индикатор качества. Исключения из знаменателя записываются в SLO-документ списком, и каждое новое проходит ревью вместе с владельцем продукта: «убрали ботов» и «убрали клиентов со старой версией приложения» в запросе выглядят одинаково, а в разговоре совсем по-разному. Правка формулы идёт так, как описано выше, рядом со старым индикатором и с объявленной датой. Тихую правку запроса снаружи от подгонки не отличить.

По-моему, сам SLO устроен так, что этому закону сопротивляется, и ломает его именно превращение в KPI. У KPI больше значит лучше, идеальный квартал — сто процентов. У SLO перевыполнение ничего не даёт: бюджет ошибок существует, чтобы его тратить, и история с Chubby выше ровно об этом. Сервис, который за квартал ни разу не опустился ниже цели, в Google отключали намеренно. У всей этой защиты есть граница. Она поднимает цену обмана, но стимул не убирает: если от цифры зависит премия, лазейку найдут в следующем квартале. Формулой стимул не снимается. Это вопрос к тому, как устроено ревью бюджета и что записано в системе мотивации. И обратная оговорка: смягчить цель или убрать из знаменателя чужой трафик бывает правильно, пример Dodo стоит выше. Правку от подгонки я отличаю по одному признаку: она сделана открыто, с записанной причиной и на глазах у тех, кто на эту цифру опирается.

  • SLI-based Alerting — алертинг строится поверх SLO Engineering; качество алертов прямо зависит от качества SLI.
  • SLO / Budget Review — ритуал, потребляющий данные SLO Engineering; без работающего ритуала SLO остаются техническим артефактом.
  • Networking — большинство SLI строятся на сетевых метриках (latency, error rate, DNS); знание сетевого стека определяет, что вообще можно измерить корректно.
  • Programming Languages — инструментирование SLI требует кода в сервисе (Prometheus client, OpenTelemetry SDK).
  • Capacity Planning — capacity planning опирается на SLO как на целевой уровень надёжности.
  • Vendor Reliability — SLA поставщиков задают нижнюю границу: без явного резервирования собственный SLO не выше произведения их обязательств на вашу собственную надёжность.
  • Symptom vs Cause Alerting — SLI на симптом — то, по чему будят дежурного; метрики причин остаются диагностическим контекстом.
  • Composite SLO Methodology — здесь про то, как формулировать SLO одного компонента, там — как складывать их для системы из многих. Читать вместе.
  • Resilience Patterns — quality SLI считает то, что там названо плавной деградацией; без уровней критичности оттуда индикатор складывает несравнимое.

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

Второе наблюдение из практики: после первой настройки формулировки SLI в командах остаются неряшливыми, вроде «≥ 99% requests success». Без ответа на «что такое request», «что такое success» и «в каком окне» это не SLI, а слоган. Хороший SLI читается как count(http_requests{status!~"5.."} | window_5m) / count(http_requests{is_synthetic="false"} | window_5m) > 0.999. Если в команде нет такой строгости — стоит обсудить, как её внедрить.

Третье — сколько бюджетов выдерживает один путь. У Mercari на CUJ их два, доступность и задержка. Quality SLI добавляет третий, и чем их больше, тем хуже я понимаю, какой из них останавливает выкатку, когда сгорел только один.