Фоновые задачи в Next.js за пределами after() и Server Actions
App Router в Next.js даёт after(), Server Actions и Route Handlers для работы после ответа. Каждый из них — правильный инструмент для своей задачи, и у каждого есть точка отказа, которая толкает к внешнему уровню воркеров. Эта страница — руководство по выбору: прочитайте таблицу, выберите нужный примитив и посмотрите, как передать работу в пайплайн Inquir, когда нужно пережить HTTP-окно.
Обновлено: 2026-06-28
- Используйте after(): быстрые побочные эффекты после ответа, которые укладываются в таймаут платформы.
- Используйте Server Actions: мутации из форм; передавайте в Inquir, когда побочный эффект медленный или должен ретраиться независимо.
- Используйте Route Handler + Inquir: явный ответ 202, задача в очереди Inquir, пользователь никогда не ждёт медленной работы.
- Используйте полный пайплайн Inquir: многошаговая оркестрация, cron-расписания, параллельный fan-out, продолжение вебхуков.
Кратко
Суть ответа
Фоновые задачи в Next.js за пределами after() и Server Actions. Ваш Server Action или Route Handler вызывает эндпоинт шлюза Inquir с API-ключом и сразу возвращает клиенту 202. Пайплайны Inquir берут на себя очередь, ретраи, секреты и историю выполнения — те же функции, что используются в шагах пайплайнов по расписанию и для вебхуков.
Когда подходит
- Побочный эффект в Server Action или Route Handler может упасть независимо, нуждается в ретраях или должен пережить таймаут платформы.
- Нужны задачи по cron-расписанию, продолжение вебхуков или параллельный fan-out с видимой историей запусков рядом с кодом App Router.
На что обратить внимание
after()и Fluid Compute — правильный выбор для работы с упором на ввод-вывод, которая укладывается в таймаут платформы: логирование, события аналитики, прогрев кеша, один вызов downstream-API.- Vercel Cron в
vercel.jsonсправляется с лёгкими задачами по расписанию, которые завершаются за секунды. Как только нужны многошаговая оркестрация, ретраи на уровне шага, видимая история запусков или работа, которая по-настоящему переживает вызов функции, нужен отдельный уровень задач.
Нагрузка и где ломается
Почему фоновые примитивы Next.js упираются в стену
after() и Server Actions откладывают работу до момента после ответа — но на Vercel она всё ещё выполняется внутри того же вызова функции с таймаутами платформы. Генерация PDF, массовые рассылки, медленные цепочки сторонних API и крупные преобразования файлов эти лимиты переживают. Примитивы не сломаны; этой работе просто не место внутри обработчика запроса.
Тогда команды тянутся к BullMQ, Inngest или отдельному контейнеру воркера. Это второй таргет деплоя, второе хранилище секретов и второй дашборд, когда вебхук Stripe или ночная синхронизация падает в три часа ночи.
Компромиссы
Когда хватает встроенных средств Next.js
after() и Fluid Compute — правильный выбор для работы с упором на ввод-вывод, которая укладывается в таймаут платформы: логирование, события аналитики, прогрев кеша, один вызов downstream-API.
Vercel Cron в vercel.json справляется с лёгкими задачами по расписанию, которые завершаются за секунды. Как только нужны многошаговая оркестрация, ретраи на уровне шага, видимая история запусков или работа, которая по-настоящему переживает вызов функции, нужен отдельный уровень задач.
Как помогает Inquir
Next.js остаётся тонким; Inquir выполняет медленный путь
Ваш Server Action или Route Handler вызывает эндпоинт шлюза Inquir с API-ключом и сразу возвращает клиенту 202. Пайплайны Inquir берут на себя очередь, ретраи, секреты и историю выполнения — те же функции, что используются в шагах пайплайнов по расписанию и для вебхуков.
Один воркспейс для HTTP-входа, пайплайнов по расписанию и асинхронных задач. Не нужно поднимать Redis и держать Dockerfile воркера рядом с репозиторием Next.js — только URL шлюза, который приложение уже умеет вызывать через fetch.
Сравнение
Таблица выбора фонового примитива Next.js
Выберите строку, которая соответствует вашей работе. У каждого примитива есть точка отказа — зная её, проще решить, когда передавать работу в пайплайн Inquir.
| Примитив | Для чего | Точка отказа | Когда нужен Inquir |
|---|---|---|---|
| after() | Быстрые побочные эффекты после ответа (аналитика, сброс кеша, один вызов API) | Всё ещё выполняется внутри вызова функции; на Vercel завершается по таймауту вместе с запросом | Работа может упасть независимо, нуждается в ретраях или переживает таймаут платформы |
| Server Action | Мутации из форм: создание, обновление, валидация — с оптимистичным UI | Долгие побочные эффекты блокируют action; таймаут завершает action и молча теряет работу | Побочный эффект (письмо, PDF, синхронизация) медленный или должен ретраиться независимо от формы |
| Route Handler (синхронный) | REST API: авторизация, CRUD, короткие подтверждения вебхуков | Не может пережить таймаут функции; медленная работа блокирует ответ клиенту | Вызывающий ожидает 202, а работа выполняется асинхронно с ретраями и историей |
| Route Handler + шлюз Inquir | Асинхронная передача: проверить ввод, поставить задачу в Inquir, сразу вернуть 202 | Добавляет сетевой переход; шлюз Inquir — внешняя зависимость | Работа медленная, нуждается в ретраях на шаг или должна отдельно идти по cron-расписанию |
| Полный пайплайн Inquir | Многошаговая оркестрация, cron-расписания, продолжение вебхуков, параллельный fan-out | Требует внешнего сервиса; больше эксплуатации, чем after() для тривиальных побочных эффектов | Нужен, когда у работы несколько шагов, она должна ретраиться на каждом или идёт по расписанию |
Что вы получаете
App Router в Next.js + Inquir: паттерны интеграции
Передача из Server Action
Server Action проверяет форму и ставит задачу в Inquir; action сразу возвращается. Шаг пайплайна выполняет медленный побочный эффект — отправку письма, сборку PDF, синхронизацию данных — вне таймаута action.
Route Handler с ответом 202
Обработчик POST в App Router проверяет ввод, вызывает шлюз Inquir и возвращает 202 до старта пайплайна. Клиент опрашивает статус, или пайплайн сам сообщает о завершении.
Продолжение вебхука
Эндпоинт шлюза Inquir подтверждает Stripe или GitHub в пределах окна таймаута провайдера, затем продолжает в шаге пайплайна. Повторные доставки провайдера не перезапускают дорогую работу.
Расписания пайплайнов шире vercel.json
Ночной ETL, ротация токенов и генерация отчётов работают как пайплайны Inquir по cron-триггеру с видимой историей запусков и ретраями на уровне шага — не хрупкий Route Handler за cron-вызовом Vercel.
Что дальше
Как подключить Next.js к пайплайнам Inquir
Server Actions и Route Handlers остаются тонкими: проверить, поставить задачу в Inquir, вернуть ответ клиенту. Пайплайны несут ретраи, секреты и историю выполнения для медленного пути.
Вынести медленную логику в функцию Inquir
Перенесите письма, PDF или синхронизацию в обработчик Inquir или шаг пайплайна. Входы держите явными; обработчики делайте идемпотентными, чтобы ретраи были безопасны.
Поставить задачу из Server Action или Route Handler
Вызовите fetch на URL шлюза Inquir с Authorization: Bearer из process.env.INQUIR_API_KEY. Верните 202 или редирект до того, как пайплайн завершится.
Следить в истории выполнения Inquir
Каждый запуск, ретрай и сбой появляется в Inquir — не нужно копаться в логах функций Vercel ради работы, которая началась в Server Action или after().
Пример кода
Server Action → Inquir: задача после отправки формы
Server Action проверяет форму и передаёт работу на эндпоинт шлюза Inquir. Эндпоинт ставит асинхронную задачу и возвращает 202. Шаг пайплайна собирает файл и уведомляет приложение. Пользователь сразу видит успех; медленная работа выполняется вне любого таймаута функций Next.js или Vercel.
'use server'; export async function requestExport(formData: FormData) { const exportId = formData.get('exportId') as string; if (!exportId) throw new Error('exportId required'); // Hand off to Inquir — returns before the pipeline finishes const res = await fetch(process.env.INQUIR_GATEWAY_URL + '/jobs/run-export', { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${process.env.INQUIR_API_KEY}`, }, body: JSON.stringify({ exportId }), }); if (!res.ok) throw new Error('Failed to queue export'); // Server Action returns; user sees success — Inquir runs the slow work }
export async function handler(event) { const { exportId } = JSON.parse(event.body || '{}'); if (!exportId) { return { statusCode: 400, body: JSON.stringify({ error: 'exportId required' }) }; } // Enqueue async work; the pipeline step runs outside the HTTP window const { instanceId: jobId } = await global.durable.startNew('run-export', undefined, { exportId }); return { statusCode: 202, body: JSON.stringify({ jobId, status: 'queued' }) }; }
export async function handler(event) { // event.payload carries the body the Server Action sent const { exportId } = event.payload ?? {}; const file = await buildExport(exportId); await storage.put(`exports/${exportId}.csv`, file); await notifyApp(exportId, file.byteLength); return { exportId, bytes: file.byteLength }; }
Когда подходит
Когда нужен пайплайн Inquir
Когда это уместно
- Побочный эффект в Server Action или Route Handler может упасть независимо, нуждается в ретраях или должен пережить таймаут платформы.
- Нужны задачи по cron-расписанию, продолжение вебхуков или параллельный fan-out с видимой историей запусков рядом с кодом App Router.
Когда лучше выбрать другое
- Вся фоновая работа укладывается в
after()или Fluid Compute, и вам не нужны история задач между запросами и ретраи на уровне шага.
Частые вопросы
Частые вопросы
Стоит ли заменять after() на Inquir?
after() на Inquir?Не всегда. after() — для быстрой работы после ответа, которая укладывается в таймаут платформы. Inquir — когда задача может упасть независимо, нуждается в ретраях, идёт по расписанию или должна пережить вызов функции.
Можно ли по-прежнему деплоить Next.js на Vercel?
Да. Эта страница про фоновые примитивы Next.js, а не про хостинг. Оставьте Vercel для App Router и edge-слоя; Inquir — уровень воркеров.
Чем это отличается от страницы про фоновые задачи для Vercel?
Страница про Vercel описывает топологию деплоя без привязки к фреймворку — какая работа живёт на Vercel, а какая в Inquir, для любого фреймворка. Эта страница сосредоточена на API именно Next.js (after(), Server Actions, Route Handlers) и точке отказа каждого примитива.
Нужна ли отдельная очередь вроде BullMQ?
Нет. Пайплайны Inquir дают очередь, ретраи и наблюдаемость. Код Next.js вызывает эндпоинт шлюза; остальным управляет Inquir.