Фоновые задачи для приложений на Vercel без клея для фоновых обработчиков
Vercel силён в UI, edge middleware, статике и предварительных версиях. Работа, которая должна пережить таймаут одной функции — письма, преобразование файлов, синхронизация данных, продолжение вебхуков, — принадлежит отдельному уровню фоновых обработчиков. Inquir — этот уровень: эндпоинт шлюза, куда ваше приложение на Vercel шлёт POST, пайплайн, который выполняет задачу, и одна консоль, где читать повторы и логи. Работает с любым фреймворком на Vercel — Next.js, SvelteKit, Nuxt, Astro.
Обновлено: 2026-10-26
- Оставить на Vercel: UI, edge middleware, статика, предварительные версии.
- Перенести в Inquir: фоновые задачи, cron-пайплайны, продолжение вебхуков, долгая обработка.
- Как это работает: приложение на Vercel делает POST на эндпоинт шлюза Inquir; эндпоинт возвращает 202 и запускает пайплайн.
Где таймауты функций Vercel становятся проблемой топологии
Serverless Functions и Edge Functions на Vercel работают внутри окна запрос — ответ. Для ответов API, переписывания в middleware и коротких асинхронных задач этого окна хватает, но генерация PDF, массовые рассылки, медленные цепочки сторонних API и ночной ETL его переживают. Платформа не сломана; этой работе просто место в другом месте.
Без отдельного уровня фоновых обработчиков команды прикручивают BullMQ + Redis, SQS или отдельно развёрнутый процесс. Это второй пайплайн деплоя, второе хранилище секретов и две панели мониторинга, которые надо проверять, когда задача тихо падает в три часа ночи, — независимо от того, на чём приложение: Next.js, SvelteKit, Nuxt или Astro.
Когда хватает одного Vercel
Vercel Cron (через vercel.json), waitUntil() в Edge Functions и Fluid Compute закрывают лёгкую асинхронную работу, которая укладывается в таймауты платформы: прогрев кеша, один вызов downstream-API или небольшая уборка по расписанию.
Если весь стек живёт на Vercel и каждый асинхронный путь укладывается в эти лимиты, второй вендор — лишние операционные расходы, которые вам могут быть не нужны.
Vercel владеет edge; Inquir — медленным путём
Ваше приложение на Vercel — на любом фреймворке — отправляет HTTP POST на эндпоинт шлюза Inquir с API-ключом. Эндпоинт ставит задачу в очередь и сразу возвращает 202. Шаг пайплайна забирает payload, выполняет медленную работу вне любого HTTP-таймаута и по завершении может вызвать ваше приложение обратно.
Фоновые задачи, cron-пайплайны и продолжение вебхуков живут в одном рабочем пространстве Inquir. Общие секреты, общая история выполнения, одно место для логов и алертов — без Redis-кластера, Dockerfile фонового обработчика и второго пайплайна деплоя.
Vercel + Inquir: паттерны топологии деплоя
Асинхронная передача с любого фреймворка
Любая серверная функция Vercel — эндпоинт SvelteKit, серверный маршрут Nuxt, API-маршрут Astro, Route Handler в Next.js — делает POST на эндпоинт шлюза Inquir и возвращает 202. Медленную работу несёт пайплайн.
Продолжение вебхука
Эндпоинт шлюза Inquir подтверждает провайдеру (Stripe, GitHub, Slack) в пределах окна таймаута, затем продолжает обработку в шаге пайплайна — повторные доставки провайдера не перезапускают дорогую работу.
Расписания пайплайнов шире vercel.json
Ночной ETL, ротация токенов и генерация отчётов работают как пайплайны Inquir по cron-триггеру с видимой историей запусков — не хрупкая серверная функция за 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 ради задачи, которая началась в серверной функции.
Vercel → Inquir: постановка задачи без привязки к фреймворку
Любое приложение на Vercel делает POST на эндпоинт шлюза Inquir. Обработчик шлюза ставит асинхронную задачу и сразу возвращает 202. Шаг пайплайна выполняет медленную работу вне любого HTTP-таймаута. Паттерн одинаков, будь вызывающий Route Handler в Next.js, серверный эндпоинт SvelteKit, серверный маршрут Nuxt или API-маршрут Astro.
// 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 Functions или Serverless Functions.
- Нужен один уровень фоновых обработчиков с общей наблюдаемостью вместо сшивания BullMQ, Redis и отдельного сервера фоновых обработчиков с проектом на Vercel.
Когда лучше выбрать другое
- Вся фоновая работа уже завершается внутри Vercel Fluid Compute или
waitUntil(), и вам не нужны история задач между запросами и повторы на уровне шага.
Частые вопросы
Работает ли это с фреймворками, кроме Next.js?
Да — подходит любое приложение на Vercel, которое может вызвать fetch в серверной функции. Серверные эндпоинты SvelteKit, серверные маршруты Nuxt и API-маршруты Astro вызывают тот же URL шлюза Inquir. Адаптер под конкретный фреймворк не нужен.
Как защитить вызов постановки задачи?
Храните API-ключ Inquir в переменных окружения Vercel. Маршрут шлюза Inquir требует bearer-токен, так что запускать задачи может только ваше приложение на Vercel.
А как же Vercel Fluid Compute?
Fluid Compute расширяет параллелизм функций на Vercel — полезно, когда работа с тяжёлым вводом-выводом укладывается в рамки запроса. Inquir — для работы, которая должна пережить HTTP-запрос, идти по расписанию или продолжаться после подтверждения вебхука.
Нужно ли управлять отдельной очередью?
Нет. Пайплайны Inquir берут на себя планирование, повторы и наблюдаемость. Приложение на Vercel просто вызывает эндпоинт шлюза Inquir — остальным управляет Inquir.