Vercel FUNCTION_INVOCATION_TIMEOUT (504): How to Fix It

Vercel returns 504 FUNCTION_INVOCATION_TIMEOUT when a function runs too long. Find the slow step, set maxDuration correctly, and move long work off the request path.

Vercel's FUNCTION_INVOCATION_TIMEOUT (HTTP 504) means your serverless function did not finish before its maximum duration; raising maxDuration buys time, but the lasting fix is finding the slow step and moving long-running work out of the request.

504: GATEWAY_TIMEOUT
Code: FUNCTION_INVOCATION_TIMEOUT

The default and maximum durations depend on your plan and compute settings, so confirm current values in the Vercel dashboard and docs rather than relying on a number you read last year.

Step 1: Find What Is Actually Slow

Do not raise limits blindly. Time each stage and log it.

export async function GET() {
  const t0 = Date.now()
  const user = await getUser()
  const t1 = Date.now()
  const report = await buildReport(user.id)   // suspect
  const t2 = Date.now()
  console.log(JSON.stringify({ route: '/api/report', getUserMs: t1 - t0, reportMs: t2 - t1 }))
  return Response.json(report)
}

Most timeouts are one of four things:

Cause Clue Fix
Slow or unindexed DB query One stage dominates Add index, paginate, cache
Cold database or far region Fast locally, slow in prod Deploy function in the DB's region
Upstream API hanging No response, no error Add a client timeout and one retry
Genuinely long job PDF, export, AI call Queue it and poll

For route-by-route percentiles, use the method in Find a Slow API Endpoint in Next.js.

Step 2: Set maxDuration on the Route

// app/api/report/route.ts
export const maxDuration = 30 // seconds, must be within your plan's cap

You can also set it per-function in vercel.json. It must stay within your plan's limit, and a higher cap is not a license to be slow. Users abandon pages long before 30 seconds.

Step 3: Time Out Your Own Calls First

If your function limit is 30 seconds and an upstream API hangs for 60, the platform kills you with a useless 504. Fail earlier with a message you control:

const res = await fetch(url, { signal: AbortSignal.timeout(8000) })

Combine this with a single retry using backoff. The full pattern is in API Timeout Errors in Node.js.

Step 4: Move Long Work Off the Request

For anything over a few seconds, accept the request, enqueue the job, return 202 Accepted with a job ID, and let the client poll or receive a webhook. Queue options include Inngest, QStash, Trigger.dev, or BullMQ on a worker; see BullMQ failed jobs monitoring for keeping the worker honest.

Step 5: Check the Database Connection Path

Pool exhaustion looks exactly like a timeout: queries wait for a free connection until the function dies. If timeouts cluster at traffic peaks, read Database Connection Pool Exhaustion. A cold-start cache or Redis call can also hang; see Redis Upstash errors on serverless.

Timeouts Are a Trend, Not an Event

A route that takes 6 seconds today and 9 seconds next month will fail suddenly. Track p95 latency per route and alert on the trend, not only on the 504.

Let Relia Catch the Slow Route Early

Relia monitors production continuously and, when requests slow down or fail, writes the incident up in plain words: what happened, why it thinks so (with a confidence level), and one thing to do next. On request it writes a fix plan, such as an index, a client timeout, or moving the work to a queue, with a "Copy for your AI assistant" button; Relia doesn't change code itself.

FAQ

What does FUNCTION_INVOCATION_TIMEOUT mean?

The function exceeded its maximum run time and Vercel terminated it, returning a 504 to the user.

How do I increase the Vercel function timeout?

Export maxDuration from the route or set it in vercel.json, within the limit of your plan. Fix the slow step too.

Why does my function time out only in production?

Production adds network distance to the database, cold starts, and real data volume. Local tests hide all three.

All guides