Trigger.dev в продакшене: как запускать фоновые задачи без боли
Фоновые задачи — это место, где AI-конвейер ломается первым
Вы написали промпт. Модель ответила. Парсер вытащил JSON. Контент красивый. Работает? Работает. На вашей машине. Один раз. С первого запуска.
А теперь запустите это 50 раз в сутки. С расписанием. С внешними API, которые возвращают 429 каждый третий запрос. С моделью, которая иногда отвечает за 2 секунды, а иногда за 45. С Replicate, у которого cold start может занять минуту. С GitHub API, который имеет rate limit 5,000 запросов в час. С Vercel deploy hook, который иногда просто не отвечает.
Это не edge-case. Это нормальный режим работы любого AI-пайплайна в продакшене. И если у вас нет инфраструктуры, которая умеет с этим жить — вы будете чинить руками. Каждый день. В выходные. В три часа ночи.
Content Factory на atlasceo.ru генерирует и публикует 5-10 статей в сутки. Полный цикл: планирование тем, генерация текста, создание иллюстраций через FAL.ai, сборка MDX, коммит в GitHub, деплой на Vercel. Всё — через Trigger.dev. И вот подробный разбор: почему, как, что сломалось и что работает.
Эволюция фоновых задач
От cron до managed infrastructure: 20 лет поиска правильного ответа
Прежде чем говорить о Trigger.dev — контекст. Фоновые задачи — это не новая проблема. Индустрия решает её 20 лет, и каждое поколение инструментов фиксило баги предыдущего, добавляя свои.
Cron + bash-скрипты. Расписание есть, retry нет, observability нет. Задача упала — узнаёшь утром из пустой базы. Или не узнаёшь. Для бэкапов и ротации логов — нормально. Для бизнес-логики — самоубийство.
Celery (Python) / Sidekiq (Ruby). Очереди на Redis/RabbitMQ. Retry есть. Мониторинг — Flower/Sidekiq Web. Но: свой Redis, свой воркер-процесс, свой деплой. Инфраструктура разрастается быстрее кода.
Bull / BullMQ (Node.js). Redis-очереди для JavaScript-мира. Хороший API, delayed jobs, rate limiting. Но всё ещё self-hosted: Redis нужно поддерживать, масштабировать, мониторить. Падение Redis = падение всего.
Temporal / Inngest. Durable execution — задачи переживают перезагрузку сервера. Temporal мощный, но порог входа как у Kubernetes: месяц на настройку, прежде чем запустишь первый workflow. Inngest проще, но vendor lock.
Trigger.dev v3. TypeScript-native. Задачи — это функции. Deploy одной командой. Dashboard с real-time логами. Retry, timeout, concurrency — декларативно. Serverless execution. Порог входа: 15 минут до первой задачи в проде.
Видите эволюцию? От «запусти скрипт и молись» до «опиши задачу как функцию, а инфраструктура сама разберётся». Trigger.dev — не революция. Это логичный итог 20 лет проб и ошибок.
Лучшая инфраструктура — та, о которой ты не думаешь. Trigger.dev не делает фоновые задачи «интересными». Он делает их скучными. А скучные задачи — это те, которые работают.
Архитектура
Cron → Task → AI → Publish: как устроен конвейер Content Factory
Content Factory — это не один скрипт. Это цепочка задач, где каждое звено зависит от предыдущего, но может быть перезапущено независимо. Вот архитектура:
Schedule (cron 05:00 UTC)
→ cf4-atlas-website-daily-plan // планирование тем на день
→ cf4-generate-article // генерация текста (Claude/GPT-4o)
→ cf4-generate-images // иллюстрации (FAL.ai FLUX Schnell)
→ cf4-assemble-mdx // сборка MDX с компонентами
→ cf4-publish-github // коммит в репозиторий
→ cf4-deploy-vercel // триггер Vercel build
Каждая стрелка — это отдельная Trigger.dev задача. Каждая задача имеет свой retry policy, свой timeout, свой concurrency limit. Падение на любом этапе не убивает весь конвейер — задача ретраится, а downstream-задачи ждут.
// Пример: задача генерации статьи с retry и timeout
export const generateArticle = task({
id: "cf4-generate-article",
retry: {
maxAttempts: 3,
factor: 2,
minTimeoutInMs: 5_000,
maxTimeoutInMs: 60_000,
},
run: async (payload: { topic: string; persona: string }) => {
const article = await generateWithClaude(payload);
// Идемпотентность: проверяем, не опубликована ли уже
const existing = await supabase
.from("articles")
.select("id")
.eq("slug", article.slug)
.single();
if (existing.data) {
logger.info("Article already exists, skipping", { slug: article.slug });
return { status: "skipped", slug: article.slug };
}
await supabase.from("articles").insert(article);
return { status: "created", slug: article.slug };
},
});
Принцип независимых звеньев
Каждая задача в цепочке — самостоятельная единица. Можно запустить cf4-generate-images отдельно, передав slug. Можно перезапустить cf4-publish-github, не перегенерируя статью. Это не монолит — это конвейер с точками входа на каждом этапе.
Три паттерна продакшена
Идемпотентность, retry, observability — без них пайплайн мёртв
Можно написать задачу за 10 минут. Можно даже задеплоить. Но без трёх паттернов она сломается в первую же неделю. Не «может сломаться». Сломается. Гарантированно.
Идемпотентность
Повторный запуск задачи не должен создавать дубликаты. Не должен публиковать статью дважды. Не должен списывать деньги за генерацию повторно. Каждая задача перед выполнением проверяет: а не сделано ли уже? Ключ дедупликации — slug статьи, content_hash, или уникальный ID задачи. Без этого один сбой сети → два поста в Telegram, два деплоя на Vercel, два списания с OpenAI.
Retry с exponential backoff
OpenAI возвращает 429? FAL.ai отвечает 503? GitHub API даёт timeout? Не паникуйте — ретрайте. Но не сразу: первый retry через 5 секунд, второй через 10, третий через 20. Exponential backoff — это уважение к API, который просит подождать. Без backoff вы получите бан вместо результата. В Trigger.dev это три строки конфига.
Structured logging
console.log('error happened') — это не логирование. Это крик в пустоту. Structured logging = JSON-события с контекстом: какой slug, какой этап, какой HTTP-код, сколько миллисекунд ушло. Trigger.dev logger пишет в dashboard, где можно фильтровать по run ID, по задаче, по статусу. Проблема найдена за минуту, а не за час.
Timeout на каждом уровне
Задача без timeout — это задача, которая может висеть вечно. Claude иногда думает 90 секунд. FAL.ai иногда думает 120. Если вы не ставите лимит — задача повисла, воркер занят, очередь растёт, новые задачи ждут. Мы ставим 120 секунд на генерацию текста, 180 на изображения, 60 на GitHub API. Если не уложились — retry.
Dead letter queue
Задача упала 3 раза подряд? Не ретрайте бесконечно. Отправьте в dead letter: запишите в Supabase с статусом 'failed', отправьте алерт в Telegram. Утром разберётесь — с полным контекстом ошибки, а не с загадочным пустым слотом в расписании.
Graceful degradation
FAL.ai не работает? Не роняйте всю статью. Опубликуйте без иллюстраций, поставьте placeholder, создайте отложенную задачу на генерацию изображений. Лучше статья без картинки, чем ноль статей. Degradation — это не баг. Это стратегия.
// Structured logging в Trigger.dev
import { logger } from "@trigger.dev/sdk/v3";
logger.info("Article generation started", {
slug: payload.slug,
persona: payload.persona,
model: "claude-sonnet-4-20250514",
});
// После завершения
logger.info("Article generation completed", {
slug: payload.slug,
tokensUsed: result.usage.total_tokens,
durationMs: Date.now() - startTime,
wordCount: result.content.split(" ").length,
});
Метрики retry за 30 дней
Из 2,100 задач: 1,970 выполнились с первой попытки (93.8%). 98 потребовали 1 retry (4.7%). 24 потребовали 2 retry (1.1%). 8 ушли в dead letter (0.4%). Ни одна публикация не потеряна. Retry — это не костыль. Это страховка, которая работает.
📬 Строите AI-конвейер или агентную систему? Подписывайтесь — разбираем паттерны продакшена без воды и маркетинга.
Подписаться в TG →Скрипты на коленке vs. Trigger.dev
Честное сравнение: что вы теряете без нормальной оркестрации
Я знаю, о чём вы думаете. «У меня cron + node-скрипт на VPS, и всё работает». Работает — пока работает. Вот что происходит, когда масштаб растёт с 5 задач в день до 50.
Скрипты на коленке (cron + VPS)
Trigger.dev production contour
Я потратил два года на cron + pm2 + ручной мониторинг. Переход на Trigger.dev занял две недели. Экономия нервов за первый месяц окупила всё. Время, потраченное на инфраструктуру — это время, не потраченное на продукт.
Сборка production-контура
7 шагов от нуля до полностью работающего пайплайна
Хватит теории. Вот конкретные шаги, которые мы прошли при миграции Content Factory на Trigger.dev. Каждый шаг — с кодом, граблями и решениями.
Инициализация проекта
npx trigger.dev@latest init в корне проекта. Создаётся trigger.config.ts с базовой конфигурацией. Указываете projectRef из dashboard, папку с задачами (src/triggers/), runtime (node). Одна команда — и скелет готов. Не пишите конфиг руками — CLI сгенерирует правильный.
Первая задача — health check
Не начинайте с бизнес-логики. Напишите задачу, которая логирует 'hello world' и возвращает timestamp. Задеплойте. Убедитесь, что dashboard показывает run. Убедитесь, что логи читаемы. Только после этого — следующий шаг. Мы пропустили это и потеряли день на дебаг проблемы, которая оказалась неправильным projectRef.
ENV-переменные через Management API
Trigger.dev CLI не имеет команды env push. Только env pull и env list. Для загрузки переменных используйте Management API: POST /api/v1/projects/{ref}/envvars/prod/import с телом { variables: { KEY: VALUE }, override: true }. Важно: чанкуйте по 20 переменных за запрос — большие body вызывают timeout.
Декомпозиция конвейера на задачи
Один монолитный скрипт 'generate-and-publish' — антипаттерн. Разбейте на атомарные задачи: планирование, генерация текста, генерация изображений, сборка MDX, публикация. Каждая задача принимает минимальный payload (slug + необходимые данные) и возвращает результат. Между задачами — triggerAndWait или batchTriggerAndWait.
Retry policy для каждого внешнего API
Не один retry policy на все задачи. У OpenAI свой rate limit, у FAL.ai свой cold start, у GitHub API свой timing. Настройте retry индивидуально: LLM — 3 попытки с backoff 5-60 сек. Генерация изображений — 2 попытки с backoff 30-120 сек (cold start!). GitHub — 3 попытки с backoff 3-15 сек.
Мониторинг и алерты
Dashboard Trigger.dev — это хорошо, но вы не будете сидеть и смотреть на него. Настройте webhook на failed runs → Telegram-бот. Мы используем простой Trigger.dev task, который при ошибке основной задачи отправляет сообщение в Telegram с: slug, этап, ошибка, ссылка на run в dashboard. Время от ошибки до алерта: < 30 секунд.
Graceful degradation и fallback
Последний и самый важный шаг. Определите: что критично, а что можно пропустить. Текст статьи — критичен, без него нечего публиковать. Иллюстрации — желательны, но не обязательны: используйте placeholder. Деплой Vercel — можно отложить и батчить. Каждая задача должна знать свой уровень критичности и уметь деградировать.
Грабля #1: ENV-переменные
Trigger.dev CLI v4 НЕ имеет команды env set или env push. Только env pull (скачать) и env list (посмотреть). Если вам нужно загрузить 50+ переменных — пишите скрипт для Management API. Мы потеряли полдня, пытаясь найти несуществующую CLI-команду.
Ошибки, которые убивают пайплайн
Антипаттерны из реального опыта — не повторяйте
За полгода эксплуатации Content Factory мы наступили на каждую возможную грабли. Вот коллекция — чтобы вам не пришлось.
Антипаттерн: нет дедупликации
Задача упала после генерации, но до записи статуса в базу. Retry создал вторую статью с тем же контентом. Два коммита в GitHub, два деплоя на Vercel, два поста в Telegram. Решение: проверка существования по slug ПЕРЕД генерацией. Используйте idempotencyKey в Trigger.dev или свою проверку в Supabase.
Антипаттерн: нет SLA на задачу
Генерация изображений через Replicate иногда занимает 5 минут (cold start GPU). Без timeout задача висит, воркер занят, очередь растёт. Через час — 15 задач в очереди, ни одна не выполняется. Решение: timeout 180 секунд + retry. Лучше перезапустить и попасть на warm instance, чем ждать бесконечно.
Неочевидный баг: часовые пояса в cron
Trigger.dev cron работает в UTC. Мы поставили schedule на ‘0 8 * * *’ думая, что это 8 утра по Москве. Это было 8 утра UTC = 11 утра по Москве. Три дня не могли понять, почему статьи публикуются не когда надо. Всегда указывайте timezone явно или считайте в UTC.
Деплой и эксплуатация
Один контракт, который не нарушается: код → прод за 60 секунд
Деплой Trigger.dev задач — это одна команда. Серьёзно. Без Docker, без Kubernetes, без CI/CD-пайплайна из 200 строк YAML.
cd ai-core && npx trigger.dev@latest deploy
Эта команда: собирает TypeScript, загружает код на Trigger.dev cloud, версионирует деплой, переключает production на новую версию. Zero-downtime. Задачи, которые выполняются в момент деплоя — дорабатывают на старой версии. Новые задачи подхватывают новую.
Что мониторим в проде:
- Dashboard Trigger.dev — real-time: текущие runs, очередь, ошибки. Открываешь — видишь всё за 5 секунд.
- Telegram-алерты — failed runs приходят в чат мгновенно. Со slug, этапом и ссылкой на run.
- Supabase таблица executions — history: все запуски, статусы, длительность. Для аналитики и дебага.
- Vercel deploy hooks — подтверждение: статья дошла до прода. Новый билд стартовал.
// Алерт в Telegram при ошибке
export const alertOnFailure = task({
id: "alert-on-failure",
run: async (payload: { taskId: string; error: string; slug: string }) => {
await bot.telegram.sendMessage(
ALERT_CHAT_ID,
`Task ${payload.taskId} failed\n` +
`Slug: ${payload.slug}\n` +
`Error: ${payload.error}\n` +
`Dashboard: https://cloud.trigger.dev/runs/...`
);
},
});
Экономика Trigger.dev
Hobby plan: $0 (до 50,000 runs/мес). Pro: $50/мес (до 500,000 runs/мес, приоритет, concurrency). Для Content Factory с 2,100 задач в месяц — Hobby хватает с запасом. Сравните с VPS за $30-50, на котором вы потратите 20 часов в месяц на поддержку инфраструктуры. $50/час вашего времени × 20 часов = $1,000 в месяц. Trigger.dev экономит вам $950.
Деплой должен быть скучным. Мониторинг должен быть скучным. Если инфраструктура вызывает эмоции — значит, инфраструктура сломана. Trigger.dev сделал наш деплой настолько скучным, что я иногда забываю, что у нас есть фоновые задачи. И это лучший комплимент.
Итог: фоновые задачи — это не код. Это дисциплина.
Trigger.dev не напишет за вас идемпотентную логику. Не придумает retry policy. Не настроит алерты. Это инструмент — как молоток. Молоток не построит дом. Но без молотка дом не построить.
Что Trigger.dev даёт: инфраструктуру, которая не мешает. Retry, timeout, concurrency, observability — из коробки. Dashboard, который показывает реальность, а не абстракцию. Deploy, который работает с первого раза.
Что вы должны дать: дисциплину. Идемпотентность в каждой задаче. Structured logging без исключений. Graceful degradation для каждого внешнего API. Алерты, которые приходят вовремя. И — самое важное — понимание, что production-пайплайн это не «написал и забыл». Это живая система, которая требует внимания. Но с правильным инструментом — минимального внимания.
Content Factory работает 6 месяцев. 5-10 статей в сутки. 99.4% успешность. Ноль потерянных публикаций. И я сплю спокойно.
Это не магия. Это инженерная дисциплина + правильный инструмент.
📬 Если строите контент-фабрику, агентный контур или AI-пайплайн — подписывайтесь. Разбираем production-паттерны каждую неделю: retry, observability, deploy, масштабирование. Без теории — только то, что работает.
Подписаться в TG →
Станислав Виниченко
Основатель Atlas CEO
"Будущее строится сейчас."
Рассылка Atlas CEO
Фронтовые сводки Сингулярности. Каждый день в 9:00. Бесплатно.
Подписаться в TelegramAtlas Graph
Что открыть дальше
Перелинковка держит пользователя внутри темы: сначала углубляем статью, затем переводим в продукт и следующий шаг.
Похожие статьи
Весь журнал →
No-code orchestration: как связать AI-агентов через n8n и Trigger.dev
Узнайте, как связать AI-агентов в единый оркестрированный процесс с помощью no-code инструментов n8n и Trigger.dev. Пошаговые инструкции, сценарии внедрения и конкретные шаги для разработки.
AI-агенты для бизнеса: полный гайд
Практический материал Atlas CEO по теме: ai-агенты, оркестрация, операции.
Trigger.dev, Temporal, n8n: оркестрация AI-агентов для бизнеса
Анализ платформ оркестрации AI-агентов: Trigger.dev, Temporal, n8n. Практические шаги внедрения, сравнение производительности, кейсы из e-commerce и финтех. Узнайте, как сократить время разработки на 40% и уменьшить ошибки на 65%.
Продукты, которые усиливают эту тему
На каждой статье даём не только чтение, но и продуктовый следующий шаг.
Content Factory
120+ постов. 8 видео. 4 лонгрида. Каждый месяц. Автоматически. В вашем стиле. На 4+ платформах. Дешевле одного копирайтера.
AI-Трансформация
Мы не «внедряем ChatGPT». Мы перестраиваем архитектуру вашего бизнеса так, чтобы AI делал 80% работы. А вы — только то, что любите.
AI Business
Мы не «внедряем AI в старые процессы». Мы превращаем вашу экспертность в AI-компанию с маржой 60–90% и глобальным масштабом.