22 февр. 2026 г.·8 мин чтения

BullMQ против Trigger.dev и cron-задач для команд Node.js

BullMQ против Trigger.dev и cron: сравнение ретраев, мониторинга и нагрузки на команду в Node.js-работе, с простыми примерами и быстрым чек-листом.

BullMQ против Trigger.dev и cron-задач для команд Node.js

Почему этот выбор потом становится болезненным

Команды редко спорят о фоновых задачах, когда приложение маленькое. Они добавляют cron-задачу для ночного отчёта, очередь для отправки писем, один скрипт для очистки старых данных и идут дальше. Боль приходит позже, когда эти маленькие задачи тихо становятся частью бизнеса.

Задачи, о которых чаще всего забывают, обычно самые скучные: выгрузка CSV для финансов, синхронизация остатков от поставщика, повторная отправка неудачных вебхуков, задача, которая каждую ночь закрывает просроченные триалы. На планёрках о них почти не говорят, но все замечают, когда они перестают работать.

Сбой ночного отчёта в 3 утра — неприятно. Кто-то просто запускает его заново, и день продолжается. Застрявшая синхронизация платежей — это уже другое. Заказы остаются в неверном состоянии, поддержка получает злые сообщения, а команда всё утро смотрит логи вместо того, чтобы чинить причину.

Поэтому этот выбор позже становится дорогим. Инструмент не просто запускает код. Он решает, что происходит после сбоя, кто увидит ошибку и сколько человеческих усилий команда потратит на поддержку здоровья задач.

Ретраи — первая линия разлома. Некоторые задачи могут упасть один раз и подождать человека. Другим нужен автоматический повтор с backoff, лимитами и чёткой точкой остановки. Если ваша схема не умеет выражать это нормально, люди начинают чинить её скриптами и ручными перезапусками.

Прозрачность важна не меньше. Когда задача пропадает в cron-логе на одном сервере, операторы гадают. Когда очередь показывает попытки, payload, историю ошибок и текущее состояние, команда может действовать за минуты, а не копаться полчаса.

Есть ещё и нагрузка на тех, кто поддерживает систему. Обычный cron кажется дешёвым, пока один человек не начнёт отвечать за каждый перезапуск, каждый пропущенный запуск и каждый загадочный дубль. Более тяжёлый инструмент может сэкономить время, если он убирает эти проверки в 3 утра. Но он же может и тратить время впустую, если задача всего лишь шлёт простой ежедневный дайджест и почти никогда не падает.

Неправильный выбор часто работает месяцами. Потом одна задача становится важной, один сбой случается в самый неудобный момент, и команда понимает, что именно она купила: поведение ретраев, видимость и дополнительную работу для того, кто первым получит алерт.

Что на самом деле делает каждый инструмент

Выбор между BullMQ, Trigger.dev и cron — это не столько вопрос популярности, сколько вопрос формы работы.

Cron-задачи — это таймеры. Они запускают команду в заданное время или через заданный интервал, например каждый час, каждую ночь или по понедельникам в 8:00. Это делает cron хорошим вариантом для маленьких повторяемых задач: очистки временных файлов, отправки одного ежедневного отчёта или ежедневной синхронизации ленты. Но cron почти не помогает, если задача падает на середине, запускается дважды или требует понятной истории повторов.

BullMQ — это очередь для Node.js, которая работает на Redis. Ваше приложение добавляет задачи в очередь, а worker-процессы забирают их и выполняют. Это хорошо подходит для задач, которые могут накапливаться, падать или требовать ретраев, не блокируя веб-сервер. Отправка писем, обработка загрузок, вызовы медленных API и обработка вебхуков — типичные примеры. BullMQ даёт ретраи, задержки, правила backoff, контроль параллелизма и чёткое разделение между приложением, которое принимает запросы, и workers, которые делают тяжёлую работу.

Trigger.dev — это job runner для асинхронных workflows. Код вы пишете сами, но вокруг него появляется больше структуры: отслеживание шагов, логи запусков, расписание, правила повторов и более понятная картина того, что случилось в каждом запуске. Лучше всего он работает тогда, когда задачи ближе к небольшим процессам, чем к одной операции. Представьте onboarding-потоки, многошаговые импорты, AI-задачи, которые работают несколько минут, или фоновую работу, которая затрагивает несколько сервисов и требует отслеживаемого прогресса.

Проще всего сформулировать так:

  • Используйте cron, когда задача маленькая, запускается по времени и безопасна для повторного запуска.
  • Используйте BullMQ, когда работа может накапливаться, требовать повторов и масштабироваться через workers.
  • Используйте Trigger.dev, когда у задачи несколько шагов и вам нужна встроенная прозрачность выполнения.

Ночная резервная копия базы данных часто хорошо ложится на cron. Всплеск из 20 000 доставок вебхуков лучше подходит для BullMQ. А workflow, который получает данные, вызывает AI-модель, ждёт результат, а потом обновляет пользователей, обычно лучше подходит для Trigger.dev. Команды попадают в неприятности, когда начинают считать эти инструменты взаимозаменяемыми. Это не так.

Начните с требований к ретраям

Поведение ретраев обычно решает вопрос быстрее любого списка функций. Большинство фоновых задач падают не потому, что код плохой. Они падают, потому что API не отвечает вовремя, соединение с базой обрывается или другой сервис говорит: «Попробуйте ещё раз через минуту».

Прежде чем выбрать инструмент, ответьте на несколько простых вопросов:

  • Как часто эта задача будет падать в обычной работе?
  • Когда она падает, помогает ли обычно ещё одна попытка?
  • Может ли задача начать с начала, или ей нужно продолжить с того места, где она остановилась?
  • Нужны ли автоматические повторы в течение часов, а не один раз?

Если сбои редки и задача простая, cron может быть достаточен. Ночной скрипт очистки или ежедневное письмо с дайджестом часто укладываются в эту модель. Если скрипт один раз не сработал, можно подождать следующего запуска или добавить небольшой retry внутри самого скрипта.

Но это перестаёт работать, когда сбой ожидаем. Допустим, ваше Node.js-приложение синхронизирует заказы со сторонним API, а тот несколько раз в день ограничивает запросы. Одной повторной попытки обычно мало. Вам может понадобиться пять попыток с интервалами в 5, 30 или 300 секунд. Это уже территория очередей. BullMQ хорошо подходит, когда нужны повторы, задержки, backoff и отдельные workers, которые продолжают попытки без лишней драмы.

Некоторым задачам нужны не только ретраи. Им нужна память. Если задача импортирует 10 000 записей, создаёт embeddings, а затем записывает результаты шаг за шагом, перезапуск с нуля будет и расточительным, и иногда опасным. Здесь workflow-инструменты вроде Trigger.dev выглядят логичнее. Они помогают, когда у задачи есть этапы, ожидания между шагами или необходимость продолжить после частичного прогресса.

Хорошо работает простое правило. Используйте cron, когда повторный запуск всей задачи дёшев. Используйте BullMQ, когда нужны более сильные правила повторов. Используйте Trigger.dev, когда нужны правила повторов плюс прогресс, состояние и восстановление по шагам.

Если неудачную задачу можно просто запустить позже ещё раз, оставьте всё простым. Если задача должна продолжать работу после проблем, выбирайте очередь или workflow-инструмент.

Смотрите на прозрачность до того, как смотреть на функции

Команды редко жалеют о том, что у них меньше функций. Чаще они жалеют о том, что не увидели проблему, пока клиент не спросил: «Почему мой отчёт так и не пришёл?» Прозрачность влияет на ежедневную работу сильнее, чем большинство списков возможностей.

Начните с жёсткого вопроса: кто первым узнаёт о сбое задачи? Если ответ — «пользователь» или «тот, кто утром смотрит логи», ваша схема уже дорогая. Эта цена не видна на странице с тарифами. Она видна в пропущенной работе, обращениях в поддержку и уставших инженерах.

Cron здесь слабее всего. Он может хорошо работать для простых задач, но прозрачность обычно приходится строить вокруг него. Вы полагаетесь на серверные логи, коды выхода, кастомные алерты и человека, который помнит, где смотреть. Если никто не построил этот слой, cron остаётся невидимым, пока что-то не сломается.

BullMQ даёт статусам задач более чёткую форму. Вы можете видеть queued, active, failed и completed задачи, а ещё добавить панель вроде Bull Board. Это большой шаг вперёд по сравнению с сырыми логами. Но всё равно кому-то нужно настраивать алерты, решать, какие сбои важны, и делать вид очереди понятным.

Trigger.dev обычно легче проверять. История запусков, повторы и трассировка шагов ближе к продукту по умолчанию, поэтому команде нужно меньше времени, чтобы собирать контекст из Redis, логов приложения и вспомогательных скриптов. Это особенно важно, когда задача затрагивает биллинг, импорты или письма клиентам.

Помогает быстрый тест:

  • Если задача упадёт в 2 ночи, кто получит уведомление?
  • Может ли кто-то увидеть последний успешный запуск меньше чем за минуту?
  • Может ли сотрудник поддержки проверить статус без помощи инженера?
  • Может ли команда отличить медленную задачу от застрявшей и от упавшей?

Неинженеры важны больше, чем кажется командам. Если статус задачи нужен операторам, поддержке или основателю, cron очень быстро создаёт трение. Им не нужен shell-доступ или grep по логам. Им нужна понятная страница статуса и понятный ответ.

Считайте прозрачность ежедневной ценой, а не приятным бонусом. Десять минут поиска по логам в день превращаются в часы каждый месяц. Для многих Node.js-команд именно эта нагрузка важнее, чем одна дополнительная опция ретрая на бумаге.

Оцените нагрузку на тех, кто поддерживает систему

Разберитесь с падающими вебхуками
Получите практичный план для ретраев, дедупликации и повторного запуска.

Большинство команд сравнивают функции и пропускают скучную часть: кто будет поддерживать систему в рабочем состоянии каждую неделю. Эта постоянная работа важнее первого запуска. Если за неё никто не отвечает, даже простой job runner превращается в набор мелких проблем.

Cron кажется лёгким, потому что начинается с одного файла и одного расписания. Скрытая цена появляется позже. Кому-то приходится замечать пропущенные запуски, дубли, частичные выполнения и задачи, которые сломались после одного неудачного вызова API. Если важны ретраи, cron часто перекладывает эту работу в собственные скрипты и долгие просмотры логов.

BullMQ даёт больше контроля, но и больше того, что нужно поддерживать. Всё ещё нужно следить за Redis, настраивать параллелизм, чистить dead jobs, повторно запускать неудачные задачи и разбираться с алертами, которые срабатывают при коротких всплесках трафика. Когда worker зависает, один человек легко может потратить 30 минут, чтобы отследить одну задачу по логам вместо решения проблемы клиента.

Trigger.dev снимает часть этой недельной нагрузки. Ретраи, история запусков и статус видны в одном месте. Для небольшой Node.js-команды это может сэкономить реальное время. Компромисс — меньше свободы в том, как придумывать собственную модель задач, но многим командам эта свобода нужна меньше, чем они думают.

Считайте работу в простых терминах:

  • правила ретраев, которые нужно настраивать после реального трафика
  • застрявшие или мёртвые задачи, которые нужно чистить или запускать заново
  • шумные алерты, которые будят кого-то просто так
  • время на чтение логов после одного сбоя
  • инциденты на выходных и кто реально на них отвечает

Будьте честны. Если один и тот же разработчик выпускает фичи, отвечает на поддержку и занимается продакшеном, это в первую очередь вопрос загрузки команды. Если никто не хочет дежурить у Redis в субботу, BullMQ не выглядит самым дешёвым вариантом. Если пропущенный отчёт просто неприятен, но не критичен, cron всё ещё может быть достаточен. Если сбои задач влияют на платежи, сообщения клиентам или состояние аккаунтов, лучшая прозрачность обычно обходится дешевле, чем один тяжёлый уикенд.

Как выбрать без лишнего усложнения

Начинайте с тех задач, которые уже есть, а не с тех, которые могут появиться через шесть месяцев. Многие Node.js-команды строят слишком сложную схему, когда выбирают один инструмент для всех фоновых задач, хотя риск у них очень разный.

Достаточно простого инвентаря. Запишите каждую задачу в одной таблице или документе: что она делает, как часто запускается, сколько обычно длится и что происходит, если она падает.

Потом сгруппируйте эти задачи по трём вещам, которые действительно меняют выбор инструмента:

  • частота
  • цена сбоя
  • время выполнения

Этот быстрый разбор говорит больше, чем список функций. Ежедневная задача по очистке без влияния на клиентов не требует той же схемы, что и ретраи счетов или синхронизация заказов.

Пусть рискованные задачи задают планку

Выбирайте самый простой инструмент, который покрывает задачи, которые вы не можете позволить себе потерять. Если задача запускается раз в ночь, выполняется за несколько секунд и её можно перезапустить вручную, cron часто достаточно.

Если задаче нужны ретраи, дедупликация или защита от наложения запусков, cron очень быстро начинает казаться слишком слабым. Вот тут BullMQ или Trigger.dev и оправдывают себя. Вы платите не за красивое расписание. Вы платите за то, чтобы избежать тихих сбоев и уборки в 2 ночи.

Небольшой пример это хорошо показывает. Допустим, приложение отправляет еженедельный дайджест, каждый час чистит просроченные сессии и повторно отправляет неудачные вебхуки платёжной системы. Дайджест и очистку сессий можно оставить простыми, если сбой дешёвый. Задачу с платёжными вебхуками лучше отдать в более сильную схему, потому что каждая ошибка может превратиться в работу поддержки или потерянную выручку.

Держите список исключений

Не загоняйте каждую задачу в одну и ту же корзину. Держите короткий список исключений для задач, которым нужна большая защита, чем остальным.

В этот список могут попасть задачи, которые касаются денег, уведомлений клиентам, сторонних API с rate limits или всего, что работает достаточно долго, чтобы наложиться на следующий запуск. Как только вы назовёте эти исключения, остальное обычно становится очевидным.

Это и есть практичный способ думать о выборе. Cron закрывает скучную, малорискованную работу. Очередь или workflow-инструмент берут на себя задачи, которые могут упасть болезненно. Большинству команд нужны оба варианта, и только нескольким задачам нужен более тяжёлый инструмент.

Реалистичный пример для Node.js

Fractional CTO для Node.js
Получите помощь Oleg с job-системами, инфраструктурой и техническим лидерством.

Выбор перестаёт быть абстрактным, когда вы размещаете все три инструмента в одном Node.js-приложении. Представьте небольшой SaaS-продукт с тремя фоновыми задачами: ночная очистка, всплеск писем после кампании и импорт клиентов, который состоит из нескольких шагов.

Ночная очистка — это обычная cron-задача. Она удаляет старые временные файлы, очищает просроченные сессии и пишет короткий лог. Если она однажды не сработает, ничего драматичного не произойдёт. Обычно её можно запустить ещё раз следующей ночью или вручную. Отладка остаётся простой, потому что вам нужен только один ответ: запускался ли скрипт вообще? Cron подходит здесь, потому что задача короткая, повторяемая и низкорисковая.

Пакетная рассылка писем гораздо лучше подходит для BullMQ. Допустим, 20 000 пользователей должны получить receipt или welcome-письмо после запуска. Часть отправок будет падать, потому что у провайдера таймаут или rate limits. С BullMQ каждое письмо может повторяться отдельно, с задержкой между попытками. Это важно. Не хочется, чтобы одна неудачная отправка требовала повторного запуска всей партии, и не хочется дублирующихся писем, если кто-то перезапустил весь процесс. Мониторинг очереди тоже сокращает время на отладку. Разработчик может открыть упавшие задачи, увидеть число попыток, проверить payload и повторно запустить только то, что сломалось.

Импорт клиентов — это место, где Trigger.dev выглядит логичнее. Представьте, что пользователь загружает CSV, приложение валидирует строки, создаёт аккаунты, отправляет приглашения, а потом отправляет краткий итог администратору. Это не одна задача. Это цепочка шагов со своим состоянием посередине. Если четвёртый шаг падает из-за таймаута в одном API-вызове, Trigger.dev может продолжить workflow без старта с нуля. История запуска показывает, где он остановился, какие данные использовались и какой шаг требует внимания. Это часто экономит час поиска по логам.

Инструмент меняет то, как команда ощущает сбой. Cron удерживает нагрузку на сопровождение низкой, но только тогда, когда задача простая и пропущенные запуски не слишком вредят. BullMQ требует Redis и workers, но быстро окупается там, где важны ретраи и мониторинг очереди. Trigger.dev добавляет больше структуры, и эта структура полезна, когда задача длится минуты, затрагивает несколько систем и требует понятной пошаговой отладки.

Ошибки, которые совершают команды

Команды часто воспринимают это как сравнение функций. На деле всё обычно превращается в операционную проблему позже. Неправильный выбор не ломается в первый день. Он ломается в 2 ночи, когда задача запускается дважды, зависает на середине или никто не может объяснить клиенту, что произошло.

Одна частая ошибка — использовать cron для работы, которая не должна пересекаться сама с собой. Cron хорош для простых, одноразовых задач. Но он становится рискованным, когда одна и та же задача может ещё работать, пока начинается следующий запуск по расписанию. Представьте Node.js-задачу, которая импортирует заказы каждые пять минут. Если один запуск длится семь минут, следующий всё равно стартует. И вот у вас дубли, race conditions и уборка, которую никто не хотел.

Противоположная ошибка тоже случается. Команды ставят BullMQ, потому что очереди кажутся более серьёзными, даже если им нужна всего одна ежедневная задача и простой retry внутри скрипта. Это добавляет Redis, worker-процессы, мониторинг очереди и ещё одну вещь, которую надо патчить и объяснять. Если в приложении три низкорисковые задачи по расписанию, очередь может создать больше поддержки, чем пользы.

Управляемым инструментам тоже часто доверяют слишком сильно. Trigger.dev убирает много вспомогательной инфраструктуры, но не убирает обработку ошибок. Вам всё равно нужно решить:

  • что считается ошибкой, которую можно повторить
  • когда следует прекратить попытки
  • как избежать побочных эффектов-дубликатов
  • кого уведомлять, если задача продолжает падать

Команды пропускают эти вопросы, а потом удивляются, когда синхронизация платежей повторяется пять раз и создаёт пять тикетов в поддержку.

Самая дорогая ошибка — не думать о людях, которые будут проверять статус задачи. Сотрудникам поддержки, основателям и операционным людям обычно нужен быстрый ответ: задача запускалась? Она зависла? Будет ли повторная попытка? Если единственный путь к ответу — «попросить инженера посмотреть логи», инструмент уже стоит слишком дорого.

Хорошие системы для задач не просто запускают код. Они делают сбой видимым и скучным. Если ваша команда не может объяснить статус задачи меньше чем за минуту, вы выбрали что-то сложнее в эксплуатации, чем это выглядело.

Быстрые проверки перед окончательным решением

Разберите свой стек задач
Получите понятный выбор между cron, BullMQ и Trigger.dev.

Прежде чем выбрать инструмент, проверьте саму задачу. Многие команды сначала сравнивают функции и пропускают простые вопросы, из-за которых потом возникают проблемы.

Ночной отчёт обычно можно запустить дважды без серьёзного вреда. Платёжное списание или отправка счёта — уже нет. Это различие часто важнее любой таблицы функций.

Используйте этот короткий фильтр перед окончательным выбором:

  • Проверьте, что будет, если задача сработает дважды. Если второй запуск создаст второе списание, второе письмо или вторую запись, вам нужна более сильная защита от повторов и дублирующихся запусков.
  • Проверьте, сколько истории вам нужно. Если команде нужно просматривать каждую попытку, каждую ошибку и итоговый результат, cron после первого инцидента часто кажется слишком слепым.
  • Проверьте, кто будет следить за сбоями. Если один человек отвечает за алерты, выходные и зависшие задачи, выбирайте схему, где у этого человека будет меньше ручной рутины.
  • Проверьте, сможет ли новый сотрудник быстро это понять. Если за десять минут у доски вы не можете объяснить схему простыми словами, она, скорее всего, слишком сложна для этой проблемы.

Команды часто пропускают третий пункт. Нагрузка на операторов звучит абстрактно, пока задача не падает в 2 ночи и кто-то не должен быстро ответить на базовые вопросы: запускалась ли она? Сколько раз? Был ли retry? Часть работы успела завершиться? Если ответы на это требуют копания в логах сразу в трёх системах, инструмент стоит дороже, чем кажется.

Ясность важна не меньше. Небольшой команде чаще помогает схема, которая чуть менее гибкая, но понятная. Если вам нужен глубокий контроль над ретраями, backoff и мониторингом очереди, BullMQ может подойти лучше. Если вам нужна более встроенная история запусков и меньше инфраструктуры вокруг очереди, Trigger.dev может сэкономить время. Если задача простая, безопасна для повторного запуска и легко проверяется, cron всё ещё может быть достаточен.

Выбирайте инструмент, который ваша команда сможет спокойно поддерживать в плохой день, а не только тот, который красиво выглядит в демо.

Что делать дальше

Не заменяйте все планировщики сразу. Начните с того, чтобы записать все задачи, которые уже запускаются сегодня, даже самые скучные. Отметьте, что их запускает, что они делают, как часто падают, кто это замечает и сколько времени команды они съедают каждый месяц.

Этот быстрый аудит обычно делает выбор понятнее любой таблицы функций. В большинстве команд только небольшая часть задач действительно создаёт боль. Ретраи платежей, синхронизация вебхуков, импортные конвейеры и уведомления пользователям обычно требуют более сильных ретраев и лучшей прозрачности. Ночная очистка, которая почти никогда не падает, часто нормально живёт на cron.

В первую очередь переносите болезненные задачи. Тихие, низкорисковые задачи оставьте в покое, пока не появится причина их трогать. Так миграция будет небольшой, риск снизится, и у команды появится чистый тестовый случай, прежде чем вы измените большую часть схемы задач.

Перед переносом запишите правила ретраев простыми словами:

  • сколько раз задача должна повторяться
  • сколько времени система должна ждать между попытками
  • когда задача должна прекратить повторы
  • кто получает алерт
  • кто отвечает за исправление

Последний пункт важнее, чем кажется. Если алерт сработал, а отвечать некому, это перестаёт быть проблемой инструмента и превращается в операционную проблему.

После первой миграции сделайте короткий разбор. Может ли команда отвечать на простые вопросы, не роясь в логах полчаса? Какие задачи упали вчера? Какие из них застряли? Какие сбои требуют действия, а какие могут подождать? Если на эти вопросы всё ещё трудно отвечать, следующим делом нужно улучшать прозрачность.

Если этот компромисс повлияет на скорость roadmap, найм или расходы в облаке, второе мнение может сэкономить время. Oleg Sotnikov на oleg.is работает со стартапами и небольшими командами над lean-инфраструктурой, наблюдаемостью и AI-first инженерными операциями. Короткий разбор ваших текущих задач покажет, нужен ли вам queue, workflow-инструмент или просто более дисциплинированный cron, прежде чем вы потратите ещё больше инженерного времени.

Часто задаваемые вопросы

Когда обычного cron достаточно?

Используйте cron для коротких задач по расписанию, которые безопасно запускать повторно и легко проверить. Скрипты очистки, один ежедневный отчёт или простое резервное копирование часто подходят. Если один неудачный запуск лишь раздражает команду и никто не теряет деньги или состояние аккаунта, cron обычно справляется.

Когда BullMQ подходит лучше, чем cron?

BullMQ подходит для работы, которая накапливается, падает рывками или требует автоматических повторов без блокировки запросов. Отправка писем, доставка вебхуков, медленные синхронизации через API и обработка файлов — типичные примеры. Он добавляет Redis и поддержку worker-процессов, поэтому используйте его, когда этот дополнительный контроль реально экономит время на поддержке и отладке.

Когда стоит выбрать Trigger.dev вместо BullMQ?

Выбирайте Trigger.dev, когда задача больше похожа на workflow, чем на одну операцию. Если вы проверяете данные, вызываете несколько сервисов, ждёте результаты и продолжаете позже, Trigger.dev даёт более понятную историю запусков и более простое восстановление. Он особенно полезен, когда перезапуск с самого начала отнимает время или создаёт риск.

Можно ли одной Node.js-приложении использовать cron, BullMQ и Trigger.dev вместе?

Да, и большинству команд так и стоит делать. Оставьте простые задачи по расписанию на cron, отправляйте тяжёлые ретраями задачи в BullMQ, а длинные многошаговые процессы размещайте в Trigger.dev. Смешанная схема сохраняет простоту там, где это возможно, и даёт более сильные инструменты только тем задачам, которым они действительно нужны.

Что стоит проверить в первую очередь перед выбором инструмента?

Начните с цены ошибки. Подумайте, что сломается, если задача пропустит один запуск, сработает дважды или остановится на середине. Этот ответ обычно полезнее любой страницы с функциями, потому что он показывает, сколько логики ретраев, истории и ручных действий вам действительно нужно.

Как ретраи влияют на выбор?

Ретраи решают, останется ли короткий сбой API маленькой проблемой или превратится в утро ручной разборки. Если всю задачу можно запустить позже ещё раз, cron может подойти. Если нужны отложенные повторы с лимитами и backoff, лучше BullMQ. Если задача должна сохранять своё состояние между шагами, чаще выигрывает Trigger.dev.

Какую прозрачность я должен видеть при сбое задачи?

В идеале вы должны видеть последний успешный запуск, текущее состояние, ошибку последнего сбоя и количество попыток повтора. Cron редко даёт такой обзор без собственной доработки. BullMQ показывает статус очереди, а Trigger.dev обычно даёт самую понятную историю запусков из коробки.

Как избежать дубликатов запусков или двойных списаний?

Напишите задачи так, чтобы повторный запуск не создавал вторую оплату, второе письмо или дублирующую запись. Сохраняйте operation ID, проверяйте текущее состояние перед действием и блокируйте пересечение запусков там, где это важно. Не полагайтесь только на расписание, когда на кону деньги или сообщения клиентам.

BullMQ — это слишком сложно для небольшого приложения?

Иногда да. Если у приложения всего несколько малорискованных задач по расписанию, а редкий сбой можно закрыть простым повтором внутри скрипта, BullMQ может добавить больше поддержки, чем пользы. Но как только задачи начинают накапливаться, упираются в rate limits или требуют повторного запуска по каждому элементу, баланс меняется.

Как мигрировать без излишнего усложнения?

Переносите в первую очередь самые болезненные задачи, а не всё сразу. Начните с ретраев платежей, синхронизации вебхуков, длинных импортов или уведомлений клиентам, потому что именно они обычно создают больше всего поддержки. Тихие задачи вроде очистки можно оставить на cron, пока не появится реальная проблема.