Технический долг: почему «работает — не трогай» обходится дороже всего
Владелец CRM жалуется, что каждая новая доработка стоит всё дороже. Два года назад добавить поле в карточку клиента занимало час, сейчас разработчики оценивают это в два дня и предупреждают, что «может что-то сломаться». Код не стал хуже сам по себе, и разработчики не разучились работать. Просто за два года в системе накопилось то, что называют техническим долгом, и теперь по нему приходится платить проценты.
Что такое технический долг
Метафору придумал программист Уорд Каннингем. Когда команда выбирает быстрое решение вместо правильного, она как будто берёт кредит: сейчас экономит время, а потом платит проценты в виде замедления всех следующих изменений. Пока долг небольшой, проценты незаметны. Когда он вырастает, большая часть времени разработчиков уходит не на новые функции, а на борьбу с последствиями старых решений.
Важно: технический долг — это не всегда ошибка. Иногда взять его — правильное бизнес-решение. Запустить продукт за два месяца с упрощённой архитектурой и проверить спрос разумнее, чем полгода строить идеальную систему для продукта, который может никому не понадобиться. Проблема начинается, когда долг не признают и не планируют его погашение.
Откуда он берётся
- Сроки. «Сделаем быстро, потом переделаем». Потом обычно не наступает.
- Устаревшие зависимости. Библиотеки и фреймворк не обновлялись годами, и теперь обновление — это отдельный проект.
- Копирование кода. Одна и та же логика скопирована в пять мест. Изменение требует найти и поправить все пять, а одно обязательно забудут.
- Отсутствие тестов. Без автоматических тестов любое изменение надо проверять вручную, а значит, медленно и не полностью.
- Смена команды. Новые разработчики не понимают, почему сделано именно так, и боятся трогать старый код.
- Изменившийся бизнес. Система проектировалась для одного филиала, а теперь их пять. Архитектура не рассчитана на это, и каждое изменение — костыль.
Как его заметить, не читая код
Владельцу бизнеса не нужно разбираться в коде, чтобы увидеть признаки долга. Достаточно следить за несколькими вещами.
| Признак | Что это обычно значит |
|---|---|
| Простые доработки оцениваются всё дороже | Код стал хрупким, изменения затрагивают много мест |
| После каждого обновления что-то ломается в неожиданном месте | Нет тестов, связи между частями системы неочевидны |
| Разработчики говорят «это лучше не трогать» | Есть участки, которые никто не понимает |
| Обновление фреймворка оценивают в месяцы | Обновления откладывались слишком долго |
| Новый разработчик входит в проект несколько недель | Нет документации, код запутан |
| Сайт или CRM постепенно замедляются | Неоптимальные запросы, накопившиеся данные без индексов |
Если вы узнали два-три пункта из таблицы, долг уже влияет на скорость и стоимость развития.
Чем опасен «работает — не трогай»
Принцип звучит разумно: если система работает, зачем тратить деньги на изменения, которых не видно? Проблема в том, что система не существует в вакууме.
Безопасность. В библиотеках регулярно находят уязвимости, и исправления выходят в новых версиях. Система, которую не обновляли два года, почти наверняка содержит известные уязвимости, для которых есть готовые инструменты атаки. Подробнее об этом в статье о кибербезопасности для бизнеса.
Совместимость. Браузеры, операционные системы серверов, платёжные сервисы и API партнёров меняются. В какой-то момент старая система перестаёт с ними работать, и исправлять приходится срочно.
Стоимость обновления растёт нелинейно. Обновиться на одну версию — несколько часов. На пять версий за раз — недели, потому что изменения накладываются друг на друга.
Люди. Хорошие разработчики неохотно берутся за проекты на устаревших технологиях. Найти команду для поддержки становится сложнее и дороже.
Как погашать долг без остановки развития
Остановить разработку новых функций на три месяца, чтобы «всё переписать», — плохая идея почти всегда. Бизнес не может ждать, а большое переписывание часто приносит новые ошибки. Работают более спокойные подходы.
- Фиксированная доля времени. Договоритесь, что 15–20% времени команды в каждом цикле уходит на погашение долга: обновления, тесты, рефакторинг. Это не мешает развитию и не даёт долгу расти.
- Правило бойскаута. Когда разработчик меняет участок кода, он оставляет его чуть чище, чем нашёл. Долг гасится там, где идёт работа, а не там, где он просто существует.
- Список долга. Команда ведёт отдельный список известных проблем с оценкой влияния. Владелец продукта видит его и может выбирать, что гасить в первую очередь.
- Тесты на критичные сценарии. Начните с автоматических тестов для того, что приносит деньги: оформление заказа, оплата, запись клиента. Они снижают страх изменений.
- Регулярные обновления зависимостей. Раз в месяц или раз в квартал, небольшими шагами.
Пример: во что обходится отложенное обновление
Условная ситуация, которая встречается регулярно. Интернет-магазин работает на фреймворке, который не обновлялся три года. За это время вышло несколько крупных версий. Платёжный провайдер объявляет, что старая версия его API будет отключена через два месяца, а новая библиотека интеграции требует свежей версии фреймворка.
Что приходится делать в такой ситуации:
- Обновить язык программирования на сервере, потому что новая версия фреймворка не работает на старой.
- Обновить фреймворк через несколько крупных версий, каждая из которых меняет что-то в поведении.
- Обновить или заменить десяток библиотек, часть из которых больше не поддерживается.
- Исправить код, который перестал работать после всех этих изменений.
- Вручную проверить весь магазин, потому что автоматических тестов нет.
- Всё это — в жёсткий срок, параллельно с обычной работой.
Если бы обновления шли регулярно, переход на новую версию платёжного API занял бы пару дней. В описанном сценарии это проект на несколько недель с риском сбоев в продажах. Разница в стоимости — в разы, и платит за неё бизнес, хотя за три года «экономии» на обновлениях никто не почувствовал никакой выгоды.
Как говорить о долге с командой
Владельцу бизнеса сложно оценить, насколько обоснована просьба разработчиков «выделить время на рефакторинг». Помогает перевести разговор с технического языка на язык последствий.
- Не «нужно переписать модуль заказов», а «изменения в оформлении заказа сейчас занимают неделю, после переработки будут занимать день».
- Не «обновить зависимости», а «в используемой версии есть известные уязвимости, вот риск, вот срок».
- Не «нет тестов», а «каждое обновление требует двух дней ручной проверки, тесты сократят это до часа».
Попросите команду формулировать задачи по долгу именно так. Тогда их можно сравнивать с задачами развития и принимать решения на понятных основаниях.
Когда переписывать всё-таки нужно
Бывают ситуации, когда постепенное улучшение не работает: система построена на технологии, которую больше не поддерживают, архитектура принципиально не подходит под новые задачи, или стоимость изменений стала больше стоимости новой разработки. Но даже тогда лучше переносить систему по частям: новый модуль рядом со старым, постепенный перенос функций, параллельная работа на время перехода.
Решение о переписывании стоит принимать после аудита, а не по ощущениям команды. Разработчики почти всегда хотят переписать чужой код, и это не всегда оправдано.
Что можно сделать прямо сейчас
- Спросите команду, какие версии фреймворка и основных библиотек используются и насколько они отстают от актуальных.
- Попросите составить список из пяти главных проблем кода с оценкой их влияния на скорость разработки.
- Проверьте, есть ли автоматические тесты хотя бы на ключевые сценарии.
- Договоритесь о регулярной доле времени на обслуживание.
Если система досталась вам от другого подрядчика или вы не уверены в её состоянии, начните с аудита. Мы проверяем код, зависимости и инфраструктуру и даём план с приоритетами — что исправить сразу, что можно отложить. Это часть нашего сопровождения, а о том, как заложить обслуживание в бюджет, читайте в статье о поддержке после запуска.
Вопросы и ответы
Можно ли вообще не иметь технического долга?
Нет, и это не нужно. Любая система, которая развивается, накапливает долг. Задача — держать его под контролем и гасить регулярно.
Сколько времени тратить на погашение долга?
Распространённая практика — 15–20% времени команды. Если долг уже большой, на несколько месяцев можно увеличить долю, но не останавливать развитие полностью.
Как понять, что пора переписывать?
Когда стоимость изменений в старой системе стабильно превышает стоимость новой разработки или технология больше не поддерживается. Это решение стоит принимать после независимого аудита.
