Великі 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)
- Бізнес хотів запускати незалежні вертикалі (новий pricing engine, окремі 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
Якщо ваш продукт уже приносить дохід, але інженерія стає вузьким місцем — починайте з малого, спочатку витягуйте читання, вимірюйте все і не намагайтеся зробити ідеально з першого разу.


