Один из самых важных показателей команды – это скорость её поставки. Об оптимизации этого параметра все вокруг говорят уже давным-давно (да я и сам целый лонгрид про расшитие бутылочных горлышек написал). Все стараются улучшать качество процессов, CI/CD, развивать своих инжеров.
Но иногда можно заметить забавный парадокс: в подразделении несколько команд, которые прекрасно и быстро работают, но общая поставка всё равно еле ползёт.
Как же так получается?
Каждая команда контролирует только свой поток работы: свой бэклог задач, спринты, релизы и так далее. При смещении фокуса внимания на уровень хотя бы нескольких команд появляется много дополнительных факторов:
- Одной команде нужно дождаться API от другой команды, у которой другие приоритеты.
- Загруженный архитектор становится боттлнеком.
- Изменения одной команды затрагивают ещё три других, и решение требует кучи согласований.
- Закончились свободные стенды для тестирования (или он вообще один).
- И множество иных причин.
В итоге в lead time появляется колоссальное количество ожидания, которое никак не разруливается на уровне одной команды.
Граф зависимостей
По сути, отношения и зависимости между командами выстраиваются в такой же граф зависимостей, какой вы можете найти у себя в коде. И этот граф точно так же может быть плотным или разреженным, однонаправленным или двунаправленным, аккуратным или запутанным до уровня современного искусства.
И в этом графе нужно очень хорошо разбираться, потому что производительность подразделения определяется не только скоростью самих команд, но и тем, как они связаны и взаимодействуют между собой. Можно ускорить одну команду на 50% и не получить общего ускорения, потому что она на каждые два дня работы будет неделю ждать смежников.
Если большинство изменений регулярно пересекает границы команд, возможно, неправильно проведены сами границы.
У меня есть прекрасная история, которая иллюстрирует эту проблему: мы делали фичу совместно с соседним отделом. Фича казалась небольшой, но её невозможно было поставить по частям, независимо. Мы собрались, окнули архитектуру и приступили к работе.
Наша часть была готова через неделю. А релиз фичи состоялся через полтора месяца, потому что у смежников полезли проблемы: то API забыли описать, то руки тестировщиков заняты чем-то другим, то ещё что-то. В итоге получилось, что общий результат был плачевным, хотя моя часть была сделана быстро.
Главная проблема была не в том, что смежники работали плохо, а в том, что результат одной команды в принципе не имел ценности без результата другой.
Где проблемы, Лебовски?
Если большинство фич регулярно требует участия нескольких команд и создаёт ожидание, то проблема скорости может быть уже не внутри команд, а в границах ответственности и архитектуре. Поэтому нужно анализировать:
- Где регулярно возникают простои.
- Какие команды блокируют друг друга и как часто.
- Какие зависимости становятся бутылочным горлышком.
- Не нужно ли поменять архитектуру (и оргструктуру заодно).
Производительность подразделения зависит не только от высокой производительности каждой команды в отдельности, но и от того, насколько они не мешают друг другу поставлять ценность (кстати, похожую модель хорошо разбирает книга «Team Topologies»). Быстрые команды не обязательно делают организацию быстрой. Иногда главная оптимизация — не ускорить команды, а убрать лишние зависимости между ними.