Крупные legacy-монолиты в 2026 году всё ещё очень распространены — особенно в B2B SaaS, финтехе, enterprise-инструментах и маркетплейсах, которые запустились 5–10 лет назад. Они работают, приносят доход, но со временем становятся всё более болезненными: медленные релизы, страх трогать код, растущий технический долг, команды наступают друг другу на пятки.
За последние 18 месяцев мы успешно мигрировали три крупных продукта (от 400 тыс. до 1,2 млн+ строк TypeScript/Node.js) на модульную архитектуру NestJS. Вот честная история — что мы делали, какие паттерны выжили в продакшене, от чего отказались и какие измеримые бизнес-результаты получили.
Почему мы решились на миграцию (бизнес-триггеры)
Решение никогда не было «NestJS — это круто». Оно было продиктовано конкретной болью:
- Среднее время релиза фичи — 3–6 недель (вместо 3–7 дней)
- Один неудачный деплой мог заблокировать весь продукт на часы
- Новым разработчикам требовалось 2–3 месяца, чтобы начать реально вносить вклад
- Затраты на инфраструктуру росли быстрее трафика (масштабирование было all-or-nothing)
- Бизнес хотел запускать независимые вертикали (новый движок ценообразования, отдельные white-label инстансы, встраиваемые модули для партнёров)
Нам нужны были независимая развёртываемость, чёткая ответственность команд и предсказуемая скорость — без полного переписывания.
Выбранная стратегия: Strangler Fig + Vertical Slice + модули NestJS
Мы сознательно не делали «большой взрывной реврайт». Вместо этого применили комбинацию трёх паттернов:
- Strangler Fig — постепенная замена частей старой системы новыми сервисами
- Vertical Slice Architecture — группировка по бизнес-возможностям, а не по техническим слоям
- NestJS как основа модулей и DI — сильная структура, отличная поддержка TypeScript, встроенная поддержка микросервисов
Как миграция выглядела на практике по фазам
Фаза 0 – Подготовка (1–2 месяца)
- Создали общую библиотеку с авторизацией, логированием, конфигурацией, валидацией, обработкой ошибок
- Ввели жёсткие правила ESLint + TypeScript для старого и нового кода
- Настроили монопо (Turborepo + Nx) с кэшированием и affected-командами
Фаза 1 – Вынос критических путей чтения (3–5 месяцев) Первыми вынесли высоконагруженные read-only эндпоинты (листинги, дашборды, отчёты) в отдельные сервисы NestJS. Почему сначала чтение? Самый низкий риск, мгновенные выигрыши в производительности (edge-кэширование + Redis), быстрый фидбек.
Фаза 2 – Командная часть + событийно-ориентированное ядро (6–12 месяцев) Перенесли операции записи и бизнес-логику. Ключевое решение: domain events стали основным протоколом коммуникации между модулями (через RabbitMQ).
Фаза 3 – Независимая развёртываемость и автономия команд (продолжается) Каждая вертикаль (billing, users, content, analytics и т.д.) стала отдельным приложением NestJS со своим репозиторием, CI/CD, подмножеством схемы базы и пайплайном деплоя.
Архитектурные решения, которые выжили в продакшене
- Модули NestJS как основная граница — каждый бизнес-домен = один модуль NestJS (позже вынесенный в самостоятельное приложение)
- Shared kernel — очень тонкий (auth, config, logger, exceptions) — без бизнес-логики
- Anti-corruption layer между старым монолитом и новыми сервисами
- RabbitMQ + domain events — для всего асинхронного и межмодульного
- Redis — везде: кэширование, rate limiting, хранилище сессий, временные блокировки
- API Gateway (Kong / Traefik) + лёгкий service mesh (linkerd) для роутинга и observability
- OpenTelemetry + Grafana Tempo — трассировка стала обязательной с первого дня
От чего мы попробовали и отказались
- Полноценные микрофронтенды → слишком тяжело для наших кейсов (остались на module federation + Next.js)
- GraphQL Federation → сложность превышала ценность (остались на REST + tRPC внутри экосистемы)
- Отдельные базы данных на сервис с самого начала → слишком болезненно для транзакционной консистентности (оставили общий Postgres с schema-per-service + eventual consistency)
- Kafka → overkill для нашего масштаба (RabbitMQ отлично справился со всем)
Измеримые результаты после 12–18 месяцев
- Частота деплоев — с 1–2 в месяц → 15–40 в неделю (по вертикали)
- Lead time for changes — с 18–42 дней → 2–7 дней
- Mean time to recover — с 4–12 часов → менее 45 минут
- Velocity — команды выдают 2,5–4× больше story points за спринт
- Рост затрат на инфраструктуру — почти плоский при 2,8× росте трафика
- Удовлетворённость разработчиков (внутренний NPS) — с 4,1 → 8,7
Текущий архитектурный набросок (2026)
- Фронтенд → Next.js App Router + React Server Components
- API-слой → Несколько приложений NestJS (по одному на крупный домен) + tRPC для внутренних вызовов
- Коммуникация → RabbitMQ (события) + Redis (кэш и синхронизация)
- Базы данных → PostgreSQL (основная) + ClickHouse (аналитика) + Redis
- Развёртывание → Kubernetes + ArgoCD + edge-функции где возможно
Итог
Миграция крупного монолита на модульную архитектуру NestJS — непростая задача, но очень стоящая, когда рост бизнеса упирается в скорость инженерии.
Самые большие победы пришли не от самого NestJS (хотя его структура помогла колоссально), а от:
- чётких границ ответственности
- событийно-ориентированного мышления
- безжалостного фокуса на развёртываемости
- инкрементального подхода Strangler Fig
Если ваш продукт уже приносит доход, но разработка стала узким местом — начинайте с малого, сначала выносите чтение, измеряйте всё и не пытайтесь сделать идеально с первого раза.
Вы уже проходили миграцию монолита в модульную архитектуру? Что было самым сложным в вашем случае?


