Comparison · Inquir Compute

Background jobs for Next.js without after() hacks or worker servers

Next.js gives you Server Actions, Route Handlers, and <code>after()</code>—but none of them replace a real background worker when PDFs, webhooks, or ETL outlive the HTTP window. Compare Next.js and Vercel background patterns with Inquir pipelines: keep the App Router on Vercel, move slow async work to serverless jobs with retries and execution history.

Last updated: 2026-06-23

  • Keep on Next.js/Vercel: App Router UI, middleware, previews, edge caching, short API responses.
  • Move to Inquir: work that exceeds function timeouts, cron beyond vercel.json limits, webhook continuation, parallel fan-out.
  • Use both: Route Handlers return 202 and call Inquir gateway routes; pipelines finish the job and notify your app.

Direct answer

Background jobs for Next.js without after() hacks or worker servers. Your Route Handler or Server Action calls an Inquir gateway route with an API key, returns 202 to the client, and moves on. Inquir pipelines handle queuing, retries, secrets, and execution history—same functions you use for webhooks and cron.

When it fits

  • Your Next.js app needs background tasks, webhooks, or cron jobs that exceed Route Handler or after() timeouts.
  • You want one async tier with shared observability instead of stitching BullMQ, Inngest, and Vercel Cron.

Tradeoffs

  • after() and Fluid Compute help when work is IO-bound and still fits inside the platform timeout—logging, cache warming, a single downstream API call.
  • Vercel Cron in vercel.json works for lightweight scheduled tasks that complete in seconds. Heavy ETL, report generation, or multi-step orchestration usually need a dedicated job tier.

Why Next.js background patterns hit a wall

Server Actions and Route Handlers are request-scoped. after() and waitUntil() defer work until after the response—but on Vercel they still run inside the same function invocation with platform timeouts. PDF generation, bulk email, slow third-party chains, and large file transforms are the usual casualties.

Teams reach for BullMQ, Inngest, or a separate worker container. That means another deploy target, another secret store, and another dashboard when a Stripe webhook or nightly sync fails at 3 AM.

When Next.js + Vercel background tooling is enough

after() and Fluid Compute help when work is IO-bound and still fits inside the platform timeout—logging, cache warming, a single downstream API call.

Vercel Cron in vercel.json works for lightweight scheduled tasks that complete in seconds. Heavy ETL, report generation, or multi-step orchestration usually need a dedicated job tier.

Next.js stays thin; Inquir runs the slow path

Your Route Handler or Server Action calls an Inquir gateway route with an API key, returns 202 to the client, and moves on. Inquir pipelines handle queuing, retries, secrets, and execution history—same functions you use for webhooks and cron.

One workspace for HTTP ingress, scheduled pipelines, and async jobs. No Redis to babysit, no worker Dockerfile beside your Next.js repo—just gateway routes your app already knows how to fetch.

Background job patterns for Next.js apps

Fast ACK from Route Handlers

App Router POST handler validates input, enqueues on Inquir, returns { status: "queued" } with 202—user never waits on PDF or email delivery.

Webhook continuation

Inquir webhook function verifies the provider signature, acks within the timeout, then continues in a pipeline step—Stripe and GitHub retries do not re-run expensive work.

Cron beyond vercel.json

Nightly ETL, token rotation, and report generation as scheduled pipelines with visible run history—not a black-box cron hitting a fragile Route Handler.

Server Action handoff

Server Actions stay for form validation and auth; heavy side effects enqueue to Inquir so you do not block the UI thread or risk Action timeouts.

How to wire background jobs from Next.js to Inquir

Route Handlers and Server Actions stay thin: validate, enqueue on Inquir, return 202. Pipelines carry retries, secrets, and execution history for the slow path.

1

Extract the slow handler to Inquir

Move PDF, email, or sync logic into an Inquir function or pipeline step. Keep inputs explicit and handlers idempotent.

2

Call from a Route Handler or Server Action

POST to the Inquir gateway with Authorization: Bearer <key> from process.env. Return 202 before the pipeline finishes.

3

Monitor in execution history

Every run, retry, and failure appears in Inquir—no digging through Vercel function logs for a job that started in after().

Next.js App Router → Inquir: enqueue after form submit

Server Action validates the form and calls an Inquir gateway route that enqueues work. The user sees success immediately; the pipeline step generates the asset and notifies your app when done.

app/actions/submit-report.ts (Server Action)
'use server';

export async function submitReport(formData: FormData) {
  const reportId = formData.get('reportId') as string;
  if (!reportId) throw new Error('reportId required');

  await fetch(process.env.INQUIR_GATEWAY_URL + '/jobs/generate-report', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.INQUIR_API_KEY}`,
    },
    body: JSON.stringify({ reportId }),
  });
  // User sees success UI; slow work runs on Inquir
}
jobs/enqueue-generate-report.mjs (Inquir HTTP handler)
export async function handler(event) {
  const { reportId } = JSON.parse(event.body || '{}');
  if (!reportId) return { statusCode: 400, body: JSON.stringify({ error: 'reportId required' }) };
  const { instanceId: jobId } = await global.durable.startNew('generate-report', undefined, { reportId });
  return { statusCode: 202, body: JSON.stringify({ jobId, status: 'queued' }) };
}
jobs/generate-report.mjs (pipeline step)
export async function handler(event) {
  const { reportId } = event.payload ?? {};
  const pdf = await buildReport(reportId);
  await storage.upload(pdf, `reports/${reportId}.pdf`);
  await notifyApp(reportId);
  return { reportId, size: pdf.byteLength };
}

When this pattern helps

When this works

  • Your Next.js app needs background tasks, webhooks, or cron jobs that exceed Route Handler or after() timeouts.
  • You want one async tier with shared observability instead of stitching BullMQ, Inngest, and Vercel Cron.

When to skip it

  • All background work fits inside after() / Fluid Compute and you do not need cross-request job history or retries beyond the platform.

FAQ

Should I replace after() with Inquir?

Not always. Use after() for quick post-response work inside the timeout. Use Inquir when the job can fail independently, needs retries, runs on a schedule, or outlives the function invocation.

Can I keep deploying Next.js on Vercel?

Yes. This page compares Next.js background patterns, not hosting. Keep Vercel for the frontend; Inquir handles the worker tier.

How is this different from background jobs for Vercel?

Same architecture—thin frontend, Inquir for slow work. This page focuses on Next.js APIs (after(), Server Actions, Route Handlers) and when each stops being enough.

Do I need a separate queue like BullMQ?

No. Inquir pipelines provide queuing, retries, and observability. Your Next.js code calls a gateway route; Inquir manages the rest.