Next.js фоновые задачи: когда after(), Server Actions и Route Handlers не хватает
App Router Next.js даёт <code>after()</code>, Server Actions и Route Handlers для работы после ответа. У каждого примитива свой профиль — и своя точка отказа, после которой нужен внешний worker-уровень. Эта страница — руководство по выбору: читайте таблицу, выбирайте нужный примитив и смотрите, как передать работу в пайплайн Inquir, когда нужно пережить HTTP-окно.
Обновлено: 2026-06-23
- Используйте after(): быстрые побочные эффекты после ответа внутри таймаута платформы.
- Используйте Server Actions: мутации из форм; передавайте в Inquir, когда побочный эффект медленный или должен повторяться независимо.
- Используйте Route Handler + Inquir: явный 202 ACK, задача в очереди Inquir, пользователь не ждёт медленной работы.
- Используйте полный пайплайн Inquir: многошаговая оркестрация, cron, параллельный fan-out, продолжение вебхуков.
Кратко
Суть ответа
Next.js фоновые задачи: когда after(), Server Actions и Route Handlers не хватает. Server Action или Route Handler вызывает шлюз Inquir с API-ключом и возвращает клиенту 202 немедленно. Пайплайны Inquir — очередь, повторы, секреты и история; те же функции, что для cron и вебхуков.
Когда подходит и когда нет
- Побочный эффект в Server Action или Route Handler может упасть независимо, нужны повторы или он выходит за таймаут платформы.
- Нужны cron-задачи, продолжение вебхуков или параллельный fan-out с видимой историей рядом с кодом App Router.
На что обратить внимание
after()и Fluid Compute — правильный выбор для IO-задач внутри таймаута: логирование, аналитика, прогрев кэша, один вызов внешнего API.- Vercel Cron в
vercel.jsonподходит для лёгких расписаний на секунды. Как только нужна многошаговая оркестрация, ретраи на уровне шага, видимая история или работа, которая реально переживает вызов функции — нужен отдельный job-уровень.
Ситуация: нагрузка и где обычно ломается
Почему фоновые примитивы Next.js упираются в лимиты
after() и Server Actions откладывают работу после ответа — но на Vercel всё ещё в рамках одного вызова функции с таймаутом платформы. PDF, массовая рассылка, медленные цепочки API и большие файловые трансформации — типичные «жертвы». Примитивы не сломаны; работа просто не должна жить в обработчике запроса.
Команды тянут BullMQ, Inngest или отдельный worker-контейнер — ещё один деплой, хранилище секретов и дашборд, когда вебхук Stripe или ночная синхронизация падают в 3 ночи.
Компромиссы
Когда хватает встроенных инструментов Next.js
after() и Fluid Compute — правильный выбор для IO-задач внутри таймаута: логирование, аналитика, прогрев кэша, один вызов внешнего API.
Vercel Cron в vercel.json подходит для лёгких расписаний на секунды. Как только нужна многошаговая оркестрация, ретраи на уровне шага, видимая история или работа, которая реально переживает вызов функции — нужен отдельный job-уровень.
Как Inquir помогает в этом сценарии
Next.js остаётся тонким; Inquir — медленный путь
Server Action или Route Handler вызывает шлюз Inquir с API-ключом и возвращает клиенту 202 немедленно. Пайплайны Inquir — очередь, повторы, секреты и история; те же функции, что для cron и вебхуков.
Одно рабочее пространство для HTTP, расписаний и async jobs — без Redis, без Dockerfile worker рядом с репозиторием Next.js, только URL шлюза, который приложение уже умеет вызывать через fetch.
Сравнение
Таблица выбора фонового примитива Next.js
Найдите строку, соответствующую вашей задаче. У каждого примитива есть точка отказа — зная её, легче решить, когда передавать работу в пайплайн Inquir.
| Примитив | Для чего | Точка отказа | Когда нужен Inquir |
|---|---|---|---|
| after() | Быстрые побочные эффекты после ответа (аналитика, сброс кэша, один API-вызов) | Работает внутри вызова функции; завершается по таймауту вместе с запросом на Vercel | Работа может упасть независимо, нужны повторы или она выходит за таймаут платформы |
| Server Action | Мутации из форм: создание, обновление, валидация — с оптимистичным UI | Долгий побочный эффект блокирует action; таймаут молча обрывает работу | Побочный эффект (email, PDF, sync) медленный или должен повторяться независимо от формы |
| Route Handler (синхронный) | REST API: auth, CRUD, быстрый ACK вебхука | Не может пережить таймаут функции; медленная работа блокирует ответ клиенту | Клиент ожидает 202 и работа должна выполняться асинхронно с повторами и историей |
| Route Handler + шлюз Inquir | Async handoff: валидация, enqueue в Inquir, 202 сразу | Добавляет сетевой hop; шлюз Inquir — внешняя зависимость | Работа медленная, нужны ретраи на шаг или она должна выполняться отдельно по cron |
| Полный пайплайн Inquir | Многошаговая оркестрация, cron, продолжение вебхуков, параллельный fan-out | Требует внешнего сервиса; больше операционных затрат, чем after() для простых эффектов | Нужен, когда у работы несколько шагов, нужны ретраи на каждом или расписание |
Что вы получаете на платформе
Next.js App Router + Inquir: паттерны интеграции
Handoff из Server Action
Server Action валидирует форму и ставит задачу в Inquir; action завершается немедленно. Шаг пайплайна выполняет медленный эффект — отправку email, сборку PDF, синхронизацию данных — вне таймаута action.
Route Handler 202 ACK
App Router POST валидирует ввод, вызывает шлюз Inquir и возвращает 202 до старта пайплайна. Клиент опрашивает или пайплайн уведомляет по завершении.
Продолжение вебхука
Шлюз Inquir подтверждает Stripe или GitHub в таймауте провайдера, тяжёлая работа — в шаге пайплайна. Повторы провайдера не перезапускают дорогостоящую работу.
Cron шире vercel.json
Ночной ETL, ротация токенов и отчёты работают как cron-пайплайны Inquir с видимой историей и ретраями на уровне шага — не хрупкий Route Handler за cron-хитом Vercel.
Что сделать дальше, по шагам
Как подключить Next.js к пайплайнам Inquir
Server Actions и Route Handlers остаются тонкими: валидация, enqueue в Inquir, ответ клиенту. Пайплайны несут повторы, секреты и историю для медленного пути.
Вынести медленную логику в функцию Inquir
Email, PDF или sync — в handler Inquir или шаг пайплайна. Входы явные; обработчики идемпотентны, чтобы ретраи были безопасны.
Enqueue из Server Action или Route Handler
fetch URL шлюза Inquir с Authorization: Bearer из process.env.INQUIR_API_KEY. Верните 202 или редирект до завершения пайплайна.
Смотреть историю выполнения в Inquir
Каждый запуск, retry и сбой — в Inquir, без поиска по логам Vercel Function за работой, начатой в Server Action или after().
Пример кода
Next.js Server Action → Inquir: enqueue после отправки формы
Server Action валидирует форму и передаёт работу в шлюз Inquir. Шлюз ставит durable job и возвращает 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' }) }; } // Queue a durable job; 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 и не нужна история job между запросами или ретраи на уровне шага.
Вопросы и ответы
Вопросы и ответы
Заменять ли after() на Inquir?
after() на Inquir?Не всегда. after() — для быстрой работы после ответа внутри таймаута платформы. Inquir — когда job может упасть отдельно, нужны ретраи, расписание или жизнь дольше вызова функции.
Можно ли оставить Next.js на Vercel?
Да. Страница про примитивы Next.js, не про смену хостинга. Vercel — для App Router и edge; Inquir — worker-уровень.
Чем отличается от «фоновых задач для Vercel»?
Страница о Vercel описывает фреймворк-агностичную топологию для Next.js, SvelteKit, Nuxt, Astro. Эта страница фокусируется на API Next.js — after(), Server Actions, Route Handlers — и точке отказа каждого примитива.
Нужна ли отдельная очередь вроде BullMQ?
Нет. Пайплайны Inquir дают очередь, повторы и наблюдаемость. Next.js вызывает шлюз; Inquir управляет остальным.