Когда лимиты таймаута serverless блокируют медленную работу
Каждая serverless-платформа ограничивает время работы функции. Для HTTP-обработчиков эти лимиты разумны, но болезненны для медленной фоновой работы: обработка больших файлов, массовая синхронизация через API, многомодельные пайплайны инференса. Выход — не более длинный таймаут, а разделение HTTP-приёма и асинхронного выполнения с цепочкой шагов пайплайна, каждый из которых укладывается в бюджет шага.
Обновлено: 2026-06-28
Кратко
Суть ответа
Когда лимиты таймаута serverless блокируют медленную работу. Inquir разделяет HTTP-приём и асинхронное выполнение. HTTP-обработчик валидирует вход, ставит durable-задачу в очередь и сразу возвращает 202 — он укладывается в таймаут любой платформы с большим запасом. Дальше задача работает вне HTTP-окна со своим бюджетом таймаута (5 с по умолчанию, настраивается до 24 часов на шаг), а очередь повторяет упавшие шаги с backoff.
Когда подходит
- Работа стабильно занимает больше HTTP-таймаута вашей платформы
- Вы упираетесь в 60 с Vercel, 900 с Lambda или 30 с CPU Workers на фоновых задачах, которые пробрались в HTTP-обработчики
На что обратить внимание
- Увеличение таймаута — временная мера, а не архитектурное решение. Работа всё равно выполняется в одном контексте с одним доменом сбоя: падение на 14-й минуте 15-минутной Lambda перезапускает все 15 минут.
- Рекурсивные вызовы (вызов самого себя, чтобы «продолжить» работу) теряют контекст между вызовами, рискуют двойной записью при сбое и невидимы для инструментов наблюдаемости, которые ждут одну трассу выполнения на задачу.
Нагрузка и где ломается
Реальные лимиты таймаута serverless-платформ
- Vercel Serverless Functions: 60 с (Pro), 300 с (Enterprise)
- AWS Lambda: максимум 900 с (15 мин)
- Cloudflare Workers: 30 с CPU-времени (план Bundled)
- Supabase Edge Functions: 60 с
Эти лимиты существуют не просто так: serverless-функции созданы для быстрых stateless HTTP-обработчиков. Проблема начинается, когда команды пытаются гнать через тот же путь выполнения фоновую работу: обработку CSV, массовую синхронизацию записей, многошаговые ML-пайплайны или ночную архивацию данных.
Компромиссы
Почему обходные пути разваливаются
Увеличение таймаута — временная мера, а не архитектурное решение. Работа всё равно выполняется в одном контексте с одним доменом сбоя: падение на 14-й минуте 15-минутной Lambda перезапускает все 15 минут.
Рекурсивные вызовы (вызов самого себя, чтобы «продолжить» работу) теряют контекст между вызовами, рискуют двойной записью при сбое и невидимы для инструментов наблюдаемости, которые ждут одну трассу выполнения на задачу.
Как помогает Inquir
Цепочки пайплайнов как выход из лимитов платформ
Inquir разделяет HTTP-приём и асинхронное выполнение. HTTP-обработчик валидирует вход, ставит durable-задачу в очередь и сразу возвращает 202 — он укладывается в таймаут любой платформы с большим запасом. Дальше задача работает вне HTTP-окна со своим бюджетом таймаута (5 с по умолчанию, настраивается до 24 часов на шаг), а очередь повторяет упавшие шаги с backoff.
Работу на часы декомпозируйте на несколько шагов: каждый шаг оставляет чекпоинт, сбой перезапускает один шаг, а пайплайн выстраивает их последовательность. Паттерны fan-out, merge и ретраев на шаг — на странице архитектуры многошаговых пайплайнов.
Сравнение
Сравнение таймаутов serverless-платформ
Лимиты HTTP-функций популярных платформ и как с ними соотносятся шаги пайплайна Inquir.
| Платформа | Лимит HTTP-функции | Фоновый / async-путь |
|---|---|---|
| Vercel | 60 с (Pro) / 300 с (Enterprise) | Встроенного фонового выполнения нет |
| AWS Lambda | Максимум 900 с (15 мин) | Async-вызов тоже ограничен 900 с |
| Cloudflare Workers | 30 с CPU-времени (Bundled) | 60 с на платном плане Unbound |
| Supabase Edge Functions | 60 с | Встроенного выполнения пайплайнов нет |
| Inquir (HTTP-обработчик) | 5 с по умолчанию / до 24 ч | — |
| Inquir (шаг пайплайна) | — | 5 с по умолчанию, до 24 ч на шаг; цепочка шагов — ради чекпоинтов |
Что вы получаете
Что даёт выполнение через пайплайн
Работа дольше лимитов HTTP-таймаута
HTTP-обработчик возвращает 202 за миллисекунды. Шаг пайплайна выполняет медленную работу со своим таймаутом — без общего контекста выполнения с HTTP-путём.
Изоляция сбоев на шаг
Сбой в шаге 3 из 5 не перезапускает шаги 1 и 2. Повторяется только упавший шаг — со своим числом попыток и политикой backoff.
Опрос статуса и колбэки
Верните jobId в ответе 202. Клиент опрашивает эндпоинт статуса или получает вебхук-колбэк, когда пайплайн завершится.
Многошаговая композиция для очень долгой работы
Цепляйте шаги: у каждого свой бюджет таймаута (5 с по умолчанию, до 24 часов), а между шагами остаются чекпоинты. Четырёхшаговый пайплайн покрывает час работы так, что сбой перезапускает один шаг, а не весь час.
Что дальше
Паттерн: HTTP принимает, пайплайн выполняет
HTTP-обработчик валидирует и запускает
Разберите вход, провалидируйте, поставьте durable-задачу в очередь, верните 202 с jobId. Это завершается с большим запасом до любого HTTP-таймаута платформы.
Шаг пайплайна делает медленную работу
Шаг работает вне HTTP-окна со своим бюджетом таймаута (5 с по умолчанию, до 24 ч). Цепляйте шаги, если работа выходит за бюджет одного шага.
Клиент опрашивает или получает колбэк
Используйте jobId для опроса эндпоинта статуса — либо пусть финальный шаг пайплайна отправит клиенту POST-вебхук по завершении.
Пример кода
Передача HTTP → пайплайн: выход из-под таймаута
HTTP-обработчик сразу возвращает 202 — он и близко не подходит к таймауту платформы. Шаг пайплайна выполняет медленную работу вне HTTP-окна.
export async function handler(event) { const { fileUrl } = JSON.parse(event.body || '{}'); if (!fileUrl) return { statusCode: 400, body: JSON.stringify({ error: 'fileUrl required' }) }; // Returns in <100ms — well inside Vercel 60s, Lambda 900s, or any other platform limit const { jobId } = await global.jobs.enqueue('import-csv', { fileUrl }); return { statusCode: 202, body: JSON.stringify({ jobId, status: 'started' }) }; }
export async function handler(event) { // Runs outside the HTTP window with its own timeout budget (up to 24 h) const { fileUrl } = event.payload ?? {}; const rows = await downloadAndParseCSV(fileUrl); // may take several minutes for large files for (const batch of chunk(rows, 500)) { await db.upsertBatch(batch); // idempotent by row ID } return { imported: rows.length, fileUrl }; }
Когда подходит
Когда применим паттерн HTTP → пайплайн
Когда это уместно
- Работа стабильно занимает больше HTTP-таймаута вашей платформы
- Вы упираетесь в 60 с Vercel, 900 с Lambda или 30 с CPU Workers на фоновых задачах, которые пробрались в HTTP-обработчики
Когда лучше выбрать другое
- Работа завершается быстрее 10 секунд — оставьте её синхронной в HTTP-обработчике ради простой отладки
Частые вопросы
Частые вопросы
Шаг пайплайна действительно не ограничен по времени?
Нет. У каждого шага пайплайна настраиваемый таймаут: 5 с по умолчанию, до 24 часов (86 400 000 мс). Это на порядки больше любого таймаута HTTP-функции, но не бесконечность. Долгую работу всё равно делите на шаги — ради чекпоинтов и ретраев одного шага; о многошаговой декомпозиции — на странице долгих serverless-задач.
Чем это отличается от поднятия таймаута Lambda до 900 с?
Lambda ограничивает всё выполнение 900 с в одном контексте. Inquir цепляет шаги, у каждого свой бюджет таймаута и независимые ретраи. Сбой на 14-й минуте одного шага не перезапускает предыдущий шаг, который уже завершился.
Что если клиенту нужен синхронный результат?
Тогда клиент опрашивает эндпоинт статуса по jobId, либо вы настраиваете финальный шаг пайплайна на POST-колбэк клиенту. По-настоящему синхронная долгая работа принципиально несовместима с HTTP-таймаутами serverless на любой платформе.