The safety of speed: How we ship code 180 times per day
Intercom рассказывает, как им удаётся выкатывать код в production около 180 раз за рабочий день со средним временем от мерджа до использования клиентами всего в 12 минут при целевой доступности 99,8%+. В январе 2026 года инженеры компании опираются на три слоя защиты: автоматизированный pipeline (сборка, параллельный CI, проверка в pre-production, rolling restart на тысячах виртуальных машин), shipping workflow с принципом «будь рядом, когда выкатываешь», активным использованием feature flags (создано более 560 флагов за три месяца) и GitHub Scientist, и модель восстановления, основанную на heartbeat-метриках и автоматических откатах. Главный фокус статьи — Ruby on Rails monolith, который деплоится в три региона хостинга. Инженеры лично следят за метриками после ship и могут тестировать предрелизный slug на отдельных production-машинах. Авторы подчёркивают: скорость — это не враг стабильности, а её предпосылка, потому что маленькие частые изменения снижают риск, а накапливаемый код его увеличивает.
«Скорость — не враг безопасности; она её необходимое условие».
В Intercom среднее время от мерджа кода до его использования клиентами в production составляет всего 12 минут.
В январе 2026 года мы в среднем делаем 180 ship’ов за рабочий день — примерно 20 деплоев в час. Принято считать, что для повышения стабильности нужно замедляться. Мы убеждены в обратном. В Intercom скорость — не враг безопасности, а её предпосылка. Накопленный код порождает риск; выкатки маленькими порциями его минимизируют. Shipping — это пульс нашей компании.
Поддерживать такую частоту, которая питает наши продуктовые инновации, и одновременно стремиться к доступности 99,8%+ — это постоянная борьба, потребовавшая более десяти лет существенных инвестиций в системы, принципы и процессы. Мы защищаем целостность наших систем тремя отдельными слоями обороны: автоматизированный pipeline, который прост, надёжен и не требует ручного вмешательства; shipping workflow, поощряющий ответственность и достаточно гибкий, чтобы guardrails работали ускорителями; и модель восстановления, оптимизированная для смягчения неизбежных сбоев. Вот как мы построили каждый слой, чтобы наша скорость оставалась главным источником стабильности.
Хотя Intercom состоит из множества сервисов и фронтенд-приложений, эта статья посвящена нашему монолиту на Ruby on Rails. Это наше основное приложение, которое мы деплоим чаще всего; кроме того, мы выкатываем его в три разных региона хостинга данных с независимыми pipeline’ами. Хотя другие сервисы (например, наш Intercom UI) следуют схожим принципам и защитным механизмам, монолит на Rails — лучший пример того, как мы доставляем код в нашем масштабе.
Автоматизированный pipeline
Спроектированный, чтобы как можно быстрее довести код от мерджа до production, обеспечивая при этом строгие проверки безопасности, наш pipeline оптимизирован одновременно для скорости и безопасности и полностью автоматизирован — большинство релизов не требуют участия человека.
Сборка и параллельное тестирование
Процесс начинается, когда инженер мерджит код в GitHub. Сразу же происходят две вещи:
Сборка: мы компилируем Rails-приложение и его зависимости в развёртываемый артефакт, который называем slug. Это занимает четыре минуты. Параллельный CI: наш набор тестов запускается параллельно со сборкой. Благодаря масштабной оптимизации, параллелизации и отбору тестов подавляющее большинство CI-сборок завершается менее чем за пять минут.
Pre-production верификация
После сборки slug разворачивается в pre-production окружении. CI не блокирует переход slug’а в pre-production. Деплой в pre-production занимает около двух минут. Это окружение не обслуживает клиентский трафик, но подключено к нашим production-хранилищам данных и зеркалирует все варианты production-инфраструктуры (например, web-сервинг, асинхронные worker’ы), и сконфигурировано так, чтобы запросы проходили через предрелизный код/worker’ы.
Сразу после деплоя мы запускаем и ждём результаты нескольких автоматизированных approval gate’ов для верификации релиза. Они отвечают на вопросы вроде:
Boot test: корректно ли приложение инициализируется на хосте? CI check: прошёл ли параллельный набор тестов? Functional synthetics: мы используем Datadog Synthetics для запуска браузерных тестов на критических флоу — например, загрузки или редактирования Fin workflow.
Если какой-либо gate провалился, релиз останавливается и не попадает в production.
Раскатка в production и rolling restarts
Как только slug одобрен для production, код продвигается на тысячи больших виртуальных машин. Мы используем оркестратор деплоя, чтобы запустить эти развёртывания одновременно, но фактический rollout децентрализован.
Это даёт ступенчатую раскатку, гарантируя, что весь флот не меняет состояние ровно в одну и ту же миллисекунду. Внутри этих больших виртуальных машин мы используем механизм rolling restart на уровне процессов:
Отдельный процесс со старым кодом выводится из пути обслуживания клиентов. Ему разрешают завершить текущую работу и корректно завершиться, как только он простаивает. Его заменяет свежий процесс с новым кодом, который возвращается в путь обслуживания.
Этот процесс гарантирует, что с момента начала деплоя первые запросы обслуживаются новым кодом уже через ~2 минуты. В течение 6 минут подавляющее большинство нашего глобального флота прозрачно обновлено без какого-либо простоя. Когда restart запущен на каждой машине, pipeline разблокирует production, чтобы можно было начать следующий деплой.
Мониторинг здоровья pipeline’а
Если фрагмент кода не проходит каждую проверку безопасности, он автоматически отклоняется ещё до того, как коснётся production-сервера. Кроме того, остановившийся pipeline мы воспринимаем как инцидент высокого приоритета: если автоматизированная система отклоняет три релиза подряд, она отправляет page on-call инженеру.
Для клиента ожидание трёх провалов может показаться долгим, но это блокировки pre-production. Мы поднимаем человека на этом этапе, потому что если линия доставки остановилась, изменения кода начинают накапливаться. Наша стабильность опирается на сборку и доставку маленькими шагами. Если pipeline остаётся заблокированным, эти крошечные шаги сливаются в большой changeset, что увеличивает риск следующего деплоя. Мы поднимаем инженера, чтобы починить pipeline и вернуться к маленьким, безопасным и частым обновлениям, которые поддерживают стабильность наших систем.
Shipping workflow
Хотя наш pipeline сильно автоматизирован, ответственность за качество кода лежит на инженере, а не на инструментах. Решение о мердже — человеческое. Наш workflow построен на принципе крайнего владения: инженер, написавший код, отвечает за его успех в production.
Будь рядом, когда выкатываешь
Один из ключевых принципов нашей культуры — ты должен быть рядом, когда выкатываешь. У нашего 12-минутного цикла деплоя есть практическая выгода: он удерживает инженера «в потоке». Когда деплой занимает часы, инженеры естественным образом переключаются на следующую задачу, встречу или обеденный перерыв. К моменту, когда их код доходит до production, контекст уже потерян, и они больше не следят.
Сохраняя деплои быстрыми, мы гарантируем, что инженер всё ещё сосредоточен на проблеме, которую только что решил. Чтобы это поддержать, наша система деплоя предоставляет:
Уведомления: автоматически пишет инженеру в Slack в момент отправки его кода и по мере прохождения этапов. Ссылки на observability: включает прямые ссылки на нужные дашборды и логи в каждый PR и сообщение в Slack. Подсказка к проверке: побуждает инженера активно «следить за стрелками» и тестировать свою фичу, как только она поднимается. Полагаться на «зелёные сборки» неприемлемо. От тебя ожидают, что ты будешь смотреть, как твоё изменение уходит в production — и если ты не готов сделать rollback, ты не готов и ship’ить.
Мы культивируем культуру без обвинений, ориентированную на вовлечённость. Когда мы видим, что инженер инициирует rollback или сразу после деплоя открывает revert, мы воспринимаем это не как провал, а как признак инженера, который активно следит за своими метриками и берёт ответственность за здоровье системы.
Feature flags
Мы активно используем feature flags, чтобы превратить деплой в не-событие. Отделяя деплой (перенос кода на серверы) от релиза (включения фичи), мы убираем blast radius новой фичи. Флаги можно включить для всех клиентов, конкретного подмножества или выключить для всех менее чем за 60 секунд через наш бэкенд UI. Инженеры могут флагать маленькие или большие изменения, группировать флаги в beta-фичи, запускать поэтапные раскатки и т. д. Мы также инвестировали в то, чтобы эти feature flags можно было использовать в приложениях за пределами Rails-монолита. Флаги позволяют включать поведение для подмножеств пользователей для тестирования перед более широким релизом, защищают от рискованных изменений и многое между. Их активно используют в Intercom: за последние три месяца мы создали более 560 флагов и активно их сопровождаем, чтобы они не превращались в постоянную сложность.
Эксперименты с GitHub Scientist
Для сложных рефакторингов — особенно тех, где поведение не должно меняться — мы используем GitHub Scientist, библиотеку для экспериментов с открытым исходным кодом. Она позволяет нам запускать «candidate»-логику (новый код) параллельно с «existing»-логикой (старым кодом) в production. Scientist автоматически инструментирует оба пути, сравнивая результаты и метрики времени в фоне. Поскольку клиенту показывается только существующее поведение, мы можем итеративно дорабатывать и проверять новый код под реальной production-нагрузкой без какого-либо риска для пользовательского опыта. Когда мы уверены, что candidate-логика верна, мы можем плавно переключиться.
Ручная верификация
До мерджа кода у инженеров есть возможность сгенерировать slug и развернуть его на виртуальной машине. Инженеры могут отсоединить работающую production-машину от пути обслуживания клиентов и развернуть на ней свой slug, подключившись к машине для ручного тестирования. Инженеры также могут разместить свой предрелизный slug на машине, обслуживающей клиентов, где он будет обслуживать небольшой процент задач или web-запросов во флоте. Single hosts позволяют нам быстро фильтровать observability по этим хостам и сравнивать/сопоставлять с production-релизом, и в целом делают низкоуровневые изменения проще и безопаснее.
Мы делаем это потому, что staging — это симуляция, а production — реальность. Никакое pre-production тестирование не может идеально имитировать хаотическое поведение миллионов пользователей. Тестируя на одном production-хосте, мы валидируем наши предположения на реальных данных, не рискуя всем флотом.
Наша модель восстановления
Размер и сложность Intercom, а также то, как клиенты используют продукт по-разному и нестандартно, нельзя воспроизвести традиционными непроизводственными окружениями и тестированием. Эти вещи по-прежнему очень важны и занимают своё место в нашем pipeline, но сбой в production неизбежен. Часть таких сбоев приведёт к деградации продукта для клиентов, а ещё меньшая часть — к outage.
В Intercom наш подход к восстановлению определяется одним основным принципом: хватит мониторить системы; начните мониторить outcomes. Традиционный мониторинг говорит, здоров ли сервер; наша модель восстановления говорит нам, здоровы ли наши клиенты.
Heartbeat-метрики: пульс Intercom
Мы опираемся на heartbeat-метрики — жизненно важные показатели, отражающие основную ценность, которую даёт наш продукт. Для Intercom это, в том числе, скорость создания комментариев (новых сообщений и ответов).
В отличие от стандартных проверок uptime, эти метрики по духу бинарны. Если скорость отправки сообщений падает ниже ожидаемого baseline, неважно, зелёные ли наши дашборды. Для клиента «лежит» значит «лежит». Если он не может делать свою работу, наш процент uptime неактуален. Отслеживая реальные показатели успешности как высокоуровневый сигнал, мы детектируем тонкие деградации, которые традиционные алерты либо пропускают, либо чрезмерно подсвечивают.
Быстрое восстановление: откаты
Поскольку мы ship’им маленькими инкрементальными шагами и держим предыдущие релизы на виртуальных машинах, наше Time to Recover (TTR) обычно очень короткое.
Автоматические откаты: если heartbeat-метрика проседает или критическая аномалия детектируется сразу после ship’а, система запускает автоматический rollback. Pipeline возвращает деплой к релизу, который работал 20 минут назад. Это часто инициирует восстановление сервиса ещё до того, как инженер откликнется на page. Ручные откаты: для сложных проблем инженеры могут запустить rollback через наш deployment UI.
Запуск ручного rollback также блокирует production pipeline. Это не даёт следующим релизам уйти в production, давая нам пространство, чтобы удалить проблемный код и провести расследование, не затрагивая клиентов.
Закаливание production
Возобновление сервиса — никогда не конец процесса. За каждым инцидентом следует incident review, но мы не просто чиним баг. Мы рассматриваем каждый инцидент как сигнал того, что наша система допустила сбой. Мы спрашиваем: как машина позволила этому случиться? — и переинжиниринг системы так, чтобы это больше не могло повториться. Поддерживая этот цикл быстрой доставки, быстрого восстановления и тщательного обучения, мы гарантируем, что наша высокая скорость остаётся главным источником стабильности.
Заключение
180 ship’ов в день — не метрика тщеславия. Это сознательный выбор ради защиты клиентского опыта. Когда окно между написанием кода и его использованием клиентами составляет 12 минут, петля обратной связи плотная, инженеры сохраняют контекст и остаются ответственными за непосредственное влияние своей работы.
Однако наша планка высока. Поддерживать такой темп требует большего, чем просто быстрый CI: нужны инженеры, которые проявляют здравый смысл и хорошо владеют основами безопасной доставки. Мы полагаемся на человеческую экспертизу, дополненную этими слоями обороны, чтобы ловить проблемы до того, как они превратятся в боль для клиента.
В Intercom мы ship’им быстро не вопреки потребности в стабильности; мы ship’им быстро, чтобы оставаться хозяевами изменений.