MVP без n8n: когда сценарий дешевле написать кодом
Я убрал n8n из стека своего MVP и собрал сценарий тонким Python-оркестратором. Рассказываю, по какому признаку это видно заранее — до того, как вы потратите вечер на схему из Code-нод.
n8n — сильный инструмент. Компания подняла $180 млн Series C и пошла в партнёрство с SAP. Это уже корпоративная история, не игрушка для энтузиастов. Я сам собираю на нём сценарии и советую его людям, которые не пишут код.
Но из последнего MVP я его выкинул. Дальше — почему.
Как я это заметил
Проект — автоматизация закупки рекламы в Telegram и VK, я один. План был очевидный: поднять n8n на VPS, собрать сценарий мышкой, за пару вечеров получить работающий контур.
Потом я сел выписывать интеграции. TGStat, Telemetr.io, Telega.in, TeleTarget, маркет-платформа VK, ОРД для маркировки рекламы. Готовой ноды нет ни для одной. Каждая — это HTTP Request с ручной авторизацией плюс Code-нода, чтобы разобрать ответ.
Выходило, что HTTP-код я напишу руками при любом раскладе. n8n сверху добавлял UI-обёртку поверх моего же кода и ещё один сервис на сервере.
Проверка на долю Code-нод
Самый честный тест, который я знаю. Прикиньте будущую схему и посчитайте узлы: сколько из них — готовые интеграции, сколько — связка HTTP Request + Code.
Больше половины готовых — берите n8n и не думайте. Code-нод под 70% и выше — вы пишете программу. Просто живёт она в текстовых полях внутри браузера: без нормального git diff, без автодополнения, без возможности запустить одну функцию в отладчике.
Плюс расходы, о которых вспоминаешь на второй неделе:
- ещё один контейнер и ещё одна база в docker compose;
- версионирование через экспорт JSON — ревью изменений превращается в чтение простыни;
- отладка только через UI и логи выполнений;
- прогнать кусок сценария локально сложнее, чем вызвать функцию из консоли.
Что я собрал вместо
Тонкий оркестратор на Python. Состояние в Postgres, запуск по расписанию, всё поднимается тем же Docker Compose.
Внутри простая машина состояний. Таблица задач со статусами, воркер берёт свободную задачу, дёргает нужный API, пишет результат и следующий статус. Повторы — поле с числом попыток и задержка. Защита от дублей — уникальный ключ на бизнес-операцию.
Десятки строк инфраструктурного кода, и всё. Остальное — те же HTTP-запросы, которые всё равно жили бы в Code-нодах. Только теперь они лежат в файлах, покрыты тестами и читаются глазами.
Когда n8n выигрывает
Чтобы не звучало как «код всегда лучше». n8n стоит брать, когда:
- основные интеграции — Google Sheets, Slack, Notion, Gmail, Telegram Bot API, Airtable. Готовые ноды закрывают тут 80% работы, включая OAuth — руками его писать скучно;
- сценарий будут править люди без опыта разработки;
- нужно показать логику заказчику: схема на экране объясняет процесс лучше любого документа;
- прототип живёт неделю, и его не жалко.
Отдельный случай: инстанс у вас уже стоит и там крутится десяток сценариев. Одиннадцатый дешевле добавить туда же, даже если он на две трети из Code-нод.
Три вопроса перед стартом
Задаю их себе до того, как что-то поднимать.
- Есть готовые ноды хотя бы для половины интеграций? Возьмите список сервисов и пройдите по нему пунктами. Ощущения тут врут.
- Кто-то кроме меня будет трогать этот сценарий? Если да, визуальный редактор окупается.
- Логика сложнее связки «если — то»? Пагинация с курсорами, лимиты API, частичные повторы шага, длинные ожидания ответа модератора. В коде это выражается прямо. В схеме превращается в лабиринт.
Два ответа против n8n — пишите кодом.
Что остаётся правдой в обоих случаях
Код тоже надо обслуживать. Появился свой оркестратор — появились свои баги, свои миграции, своя ответственность за ретраи. n8n эту часть берёт на себя. Вот его настоящая ценность: готовая исполняющая среда. Скорость мышки тут дело десятое.
Так что всё упирается в один вопрос: сколько чужого кода вы реально используете. Много — платите за среду и радуйтесь. Почти ничего — вы содержите сервис ради того, чтобы он по расписанию запускал ваш собственный скрипт. С этим справится cron.
Моё MVP запустилось без n8n. Схему процесса я всё равно нарисовал — в Markdown, рядом с кодом. Она обновляется тем же коммитом и никого не просит поднимать контейнер, чтобы её прочитать.