The post has been translated automatically. Original language: Russian
Early-stage founders and engineers often believe that if you immediately think about a scalable architecture, use the best technology stacks, and write tests as you develop, you can grow without "crutches" and technical debt.
But, as it seems to me, it is almost impossible to build something working, large-scale and completely avoid technical debt in practice (at least in the b2b direction, where noticeable functionality is needed).
Why, in my opinion, is trying to write "for the ages" from day one a self-deception or an illusion?:
The speed of hypothesis testing almost always kills the purity of the code
As a rule, at the start, a business buys survival at the price of compromise. If you sharpen the architecture for millions of loads and perfect UX-UI before the first 50 contracts are closed, the project's money will most likely run out before the product itself appears.
Dynamics of the 21st century
Currently, no architect/businessman (etc.) knows where the business model will turn in two or three years, what new trends, requests, requirements of customers, the market, and regulators will appear. To build an architecture "for decades" in such conditions is, let's say, a difficult and difficult task.
The evolution of technology and the environment
Technologies are developing rapidly and permanently, system components, security standards, integration requirements, and data protection are changing. There are more and more new legal requirements for solutions and platforms. Even the perfect code from five years ago will probably no longer look relevant and flawless today.
The human factor, the growth of competencies
Teams change, employees grow in competencies, gain new skills and knowledge, use new components and approaches - all this is an inevitable and natural process that significantly changes both the "standards of ideality and effectiveness" of solutions, as well as the internal integrity of the code base and the solutions used.
If we recognize that technical debt is not an engineering or architectural mistake, but a natural companion of business growth, then the key issue changes.: how to live with him and not let him bury the decision?
Some thoughts on practical architectural debt management:
- Stop being ashamed of having an imperfect code and treat it as some form of technical loan
Debt itself is not dangerous. "Predatory interest rates" are dangerous - when, due to complicated connections, the implementation of an elementary feature is delayed from a week to two months, and support is drowning in bug analysis. It is necessary to pay off not the entire debt, but only those areas that directly burn the operating margin and delay the release of the necessary functionality.
- Approve quotas for refactoring and code base optimization
One of the most common mistakes is to invest 100% of resources in the appearance of new features, functions, modules, etc.
Working practice - 15-20% should be allocated for planned work on system refactoring, optimizing slow database queries, security issues, etc. This will keep the technical debt at a controlled level without the need for emergency stops in development.
"The "evolutionary" "squeeze-out" principle instead of the "big bang," freezing a business for six months on the basis of "rewriting everything from scratch," almost always ends in disaster. It is much safer and more efficient to isolate the most problematic and loaded parts of the project and gradually bring them to offline services through clear interfaces (APIs), while the old monolith continues to stably serve the basic scenarios.
I assume that if there is no technical debt in a project, it is most likely only at the initial stage of development or it is a product that few people need.
And the key question of technical debt is not how to avoid it, but whether the project has the managerial discipline to regularly "pay interest on this loan" and keep its volume under control.
Colleagues, founders and technical leaders: what proportion of development resources do you consistently allocate to clearing the rubble of the past so that the business does not lose momentum?
Good luck to all and don't get sick!
Среди фаундеров и инженеров на ранних стадиях разработки продуктов часто имеется убеждение, что если сразу продумать масштабируемую архитектуру, использовать лучшие стеки технологий, писать тесты по мере разработки, то можно вырасти без "костылей" и техдолга.
Но, как мне кажется, построить что-то рабочее, масштабное и полностью избежать технического долга на практике практически невозможно (по крайней мере в b2b направлении, где нужна заметная функциональность).
Почему, на мой взгляд, попытка писать "на века" с первого дня - это самообман или иллюзия:
Скорость проверки гипотез почти всегда убивает чистоту кода
Как правило, на старте бизнес покупает выживание ценой компромиссов. Если затачивать архитектуру под миллионные нагрузки и идеальный UX-UI до того, как закрыты первые 50 контрактов, деньги проекта скорее всего кончатся раньше, чем появится сам продукт.
Динамика 21 века
Сейчас ни один архитектор/бизнесмен (и т.д) не знает, куда свернет бизнес-модель через два-три года, какие появятся новые тренды, запросы, требования клиентов, рынка, регуляторов. Выстроить в таких условиях архитектуру "на десятилетия" - задача, скажем, непростая и трудновыполнимая.
Эволюция технологий и среды
Технологии развиваются стремительно и перманентно, меняются компоненты систем, стандарты безопасности, требования к интеграциям, к защите данных. Появляются все новые и новые законодательные требования к решениями и платформам. Даже идеальный код пятилетней давности сегодня скорее всего не будет уже выглядеть актуальным и безупречным.
Человеческий фактор, рост компетенций
Команды меняются, сотрудники растут в компетенциях, получают новые навыки и знания, используют новые компоненты и подходы - все это неизбежный и естественный процесс, который заметно меняет как "стандарты идеальности и эффективности" решений, так и внутреннюю целостность кодовой базы и используемых решений
Если признать, что техдолг - это не инженерная или архитектурная ошибка, а естественный спутник роста бизнеса, то ключевой вопрос меняется: как с ним жить и не дать ему похоронить решение?
Некоторые мысли по практическому управлению архитектурным долгом:
- Перестать стыдиться наличия не идеального кода и относится к этому как к некоторой форме технического кредита
Сам по себе долг не опасен. Опасны "грабительские проценты" - когда из-за запутанных связей внедрение элементарной фичи затягивается с недели до двух месяцев, а саппорт тонет в разборе багов. Гасить нужно не весь долг, а только те участки, которые напрямую сжигают операционную маржу и затягивают выход необходимого функционала
- Утвердить квоты на рефакторинг и работы по оптимизации кодовой базы
Одна из самых распространенных ошибок - вкладывать 100% ресурсов в появление новых фич, функций, модулей и т.д
Рабочая практика - 15–20% должны выделяться на плановые работы по рефакторингу системы, оптимизации медленных запросов к базам, вопросам безопасности и т.д. Это будет удерживать техдолг на контролируемом уровне без необходимости экстренных остановок в развитии
- Принцип «эволюционного выдавливания» вместо «большого взрыва» Заморозка бизнеса на полгода с основанием "перепишем все с нуля" почти всегда заканчивается катастрофой. Гораздо безопаснее и эффективнее изолировать самые проблемные и нагруженные части проекта и постепенно выносить их в автономные сервисы через понятные интерфейсы (API), пока старый монолит продолжает стабильно обслуживать базовые сценарии.
Предполагаю, что если в каком-то проекте нет техдолга - скорее всего, он только на начальном этапе развития или же это продукт, который мало кому нужен.
А ключевой вопрос техдолга не в том, как его избежать, а в том, хватает ли у проекта управленческой дисциплины регулярно "платить проценты по этому кредиту" и держать под контролем его объем.
Коллеги, фаундеры и техлиды: какую долю ресурсов разработки вы стабильно выделяете на расчистку завалов прошлого, чтобы бизнес не терял темп?
Всем успехов и не болеть!