Фоновые задачи для Vercel без worker-клея
Vercel отлично справляется с UI, edge middleware, статикой и preview-деплоями. Работа, которая должна пережить таймаут функции — email, файловые трансформации, синхронизация данных, продолжение вебхуков — относится к отдельному worker-уровню. Inquir — этот уровень: шлюз, куда отправляет POST любое Vercel-приложение, и пайплайн, который выполняет работу. Работает с любым Vercel-фреймворком — Next.js, SvelteKit, Nuxt, Astro.
Обновлено: 2026-06-28
- Оставить на Vercel: UI, edge middleware, статика, preview-деплои.
- Перенести в Inquir: фоновые задачи, cron-пайплайны, продолжение вебхуков, долгая обработка.
- Как работает: Vercel-приложение делает POST на шлюз Inquir; шлюз возвращает 202 и запускает пайплайн.
Кратко
Суть ответа
Фоновые задачи для Vercel без worker-клея. Любое Vercel-приложение — на любом фреймворке — делает HTTP POST на шлюз Inquir с API-ключом. Шлюз ставит задачу в очередь и возвращает 202 немедленно. Шаг пайплайна берёт payload и выполняет медленную работу вне любого HTTP-таймаута, при необходимости уведомляя приложение по завершении.
Когда подходит и когда нет
- Любое Vercel-приложение — Next.js, SvelteKit, Nuxt, Astro — нуждается в фоновых задачах, вебхуках или cron, которые выходят за рамки таймаутов edge/serverless функции.
- Нужен один worker-уровень с общей наблюдаемостью вместо BullMQ, Redis и отдельного worker-сервера рядом с Vercel-проектом.
На что обратить внимание
- Vercel Cron (через
vercel.json),waitUntil()в Edge Functions и Fluid Compute закрывают лёгкую async-работу внутри таймаута — прогрев кэша, один вызов внешнего API, небольшая scheduled-уборка. - Если весь стек уже на Vercel и каждый async-путь укладывается в эти лимиты, ещё один вендор — лишние операционные расходы.
Ситуация: нагрузка и где обычно ломается
Где таймауты Vercel становятся проблемой топологии
Serverless Functions и Edge Functions Vercel работают внутри окна запрос/ответ. Для API-ответов, middleware и коротких async-задач этого хватает — но PDF, массовая рассылка, медленные цепочки API и ночной ETL выходят за это окно. Платформа не сломана; работа просто не должна жить в обработчике запроса.
Без отдельного worker-уровня команды прикручивают BullMQ+Redis, SQS или отдельный процесс. Второй деплой, второе хранилище секретов и два дашборда — вне зависимости от того, какой Vercel-фреймворк использует команда.
Компромиссы
Когда хватает одного Vercel
Vercel Cron (через vercel.json), waitUntil() в Edge Functions и Fluid Compute закрывают лёгкую async-работу внутри таймаута — прогрев кэша, один вызов внешнего API, небольшая scheduled-уборка.
Если весь стек уже на Vercel и каждый async-путь укладывается в эти лимиты, ещё один вендор — лишние операционные расходы.
Как Inquir помогает в этом сценарии
Vercel владеет edge; Inquir — медленным путём
Любое Vercel-приложение — на любом фреймворке — делает HTTP POST на шлюз Inquir с API-ключом. Шлюз ставит задачу в очередь и возвращает 202 немедленно. Шаг пайплайна берёт payload и выполняет медленную работу вне любого HTTP-таймаута, при необходимости уведомляя приложение по завершении.
Фоновые задачи, cron-пайплайны и продолжение вебхуков живут в одном рабочем пространстве Inquir: общие секреты, общая история выполнения, одно место для логов и алертов — без Redis-кластера, Dockerfile worker и второго деплоя.
Что вы получаете на платформе
Топологические паттерны Vercel + Inquir
Async handoff с любого фреймворка
Serverless-функция Vercel — SvelteKit endpoint, Nuxt server route, Astro API route или Next.js Route Handler — делает POST на шлюз Inquir и возвращает 202; пайплайн несёт медленную работу.
Продолжение вебхука
Шлюз Inquir подтверждает провайдеру (Stripe, GitHub) в пределах таймаута, тяжёлая часть — в шаге пайплайна; ретраи провайдера не перезапускают дорогостоящую работу.
Cron шире vercel.json
Ночной ETL, ротация токенов и отчёты работают как cron-пайплайны Inquir с видимой историей — не хрупкий serverless Route Handler за cron-хитом Vercel.
Параллельный fan-out
Параллельный узел пайплайна разветвляется на несколько шагов после ответа 202 — N писем, N файлов или N API без блокировки пользователя или Vercel-функции.
Что сделать дальше, по шагам
Как подключить фоновые задачи из Vercel к Inquir
Vercel-приложение не меняется — только один fetch-вызов. Шлюз Inquir ставит задачу и возвращает 202. Шаг пайплайна несёт медленную работу и при необходимости возвращает результат.
Создать шлюз и шаг пайплайна в Inquir
HTTP-обработчик ставит асинхронную задачу и возвращает 202; логика работы — в отдельном шаге пайплайна со stateless-входами.
POST из Vercel-приложения
В любом месте Vercel-приложения — SvelteKit, Nuxt, Astro или Next.js — fetch на URL шлюза Inquir с Authorization: Bearer из переменной окружения. Верните 202 пользователю до завершения пайплайна.
Смотреть историю выполнения в Inquir
Каждый прогон, ретрай и результат — в одной консоли, без поиска по логам Vercel Function.
Пример кода
Vercel-приложение → Inquir: фреймворк-агностичный паттерн
Любое Vercel-приложение делает POST на шлюз Inquir. Шлюз ставит асинхронную задачу и возвращает 202 немедленно. Шаг пайплайна выполняет медленную работу вне любого HTTP-таймаута. Паттерн одинаков для Next.js Route Handler, SvelteKit server endpoint, Nuxt server route или Astro API route.
// Runs in any Vercel serverless function: SvelteKit, Nuxt, Astro, Next.js, etc. async function enqueueBackgroundJob(payload) { const res = await fetch(process.env.INQUIR_GATEWAY_URL + '/jobs/process-upload', { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${process.env.INQUIR_API_KEY}`, }, body: JSON.stringify(payload), }); // Gateway always returns 202; job runs in the Inquir pipeline return res.json(); // { jobId, status: 'queued' } }
export async function handler(event) { const body = JSON.parse(event.body || '{}'); if (!body.uploadId) { return { statusCode: 400, body: JSON.stringify({ error: 'uploadId required' }) }; } // Enqueue async work; returns immediately — the pipeline step runs outside the HTTP window const { instanceId: jobId } = await global.durable.startNew('process-upload', undefined, body); return { statusCode: 202, body: JSON.stringify({ jobId, status: 'queued' }) }; }
export async function handler(event) { // event.payload carries the body the Vercel app sent const { uploadId, userId } = event.payload ?? {}; const result = await transformFile(uploadId); await storage.put(`processed/${uploadId}`, result); await notifyUser(userId, uploadId); return { uploadId, bytes: result.byteLength }; }
Когда подходит и когда нет
Когда эта топология помогает
Когда это уместно
- Любое Vercel-приложение — Next.js, SvelteKit, Nuxt, Astro — нуждается в фоновых задачах, вебхуках или cron, которые выходят за рамки таймаутов edge/serverless функции.
- Нужен один worker-уровень с общей наблюдаемостью вместо BullMQ, Redis и отдельного worker-сервера рядом с Vercel-проектом.
Когда лучше выбрать другое
- Вся фоновая работа выполняется внутри Fluid Compute или
waitUntil()и не нужна история задач между запросами или ретраи на уровне шага.
Вопросы и ответы
Вопросы и ответы
Работает ли это с фреймворками кроме Next.js?
Да — любое Vercel-приложение, способное вызвать fetch в serverless-функции. SvelteKit server endpoints, Nuxt server routes и Astro API routes вызывают тот же URL шлюза Inquir. Адаптер для конкретного фреймворка не нужен.
Как защитить enqueue-вызов?
API-ключ Inquir в переменных окружения Vercel. Маршрут шлюза требует bearer-токен — только ваше Vercel-приложение может ставить задачи.
А Vercel Fluid Compute?
Fluid Compute расширяет concurrency для serverless functions — полезно, когда IO-работа укладывается в scope запроса. Inquir — когда задача должна пережить HTTP-запрос, идти по расписанию или продолжаться после ACK вебхука.
Нужна ли отдельная очередь?
Нет. Пайплайны Inquir дают планирование, ретраи и наблюдаемость. Vercel-приложение просто вызывает шлюз — остальное делает Inquir.