Vercel 504: FUNCTION_INVOCATION_TIMEOUT (task timed out)

Filed under Deployment failures

Most likely causeAbout 10 min · 6 steps

Your function spent its whole time allowance waiting — usually on a slow database query or a slow outside call like an AI model — and Vercel ended it before it could reply.

Find what the function is waiting on
Raise maxDuration within your plan
Move slow jobs to the background

Fastest route

Give your AI this prompt

Copy it, replace the bracketed part with your error, and send it.

Preview the prompt
One of my Vercel API routes fails with 504 FUNCTION_INVOCATION_TIMEOUT ("Task timed out"). The route is: [path, e.g. app/api/generate/route.ts]. My Vercel plan is: [Hobby / Pro]. Here is what the route does, in order: [list the database queries and outside calls it makes]. From Vercel's logs, the function dies at about [N] seconds.

Please: 1) tell me which step is most likely eating the time and how I can confirm it, 2) add the correct maxDuration export for my plan — and tell me plainly if the work cannot fit inside my plan's limit no matter what, 3) rewrite sequential awaits that could run in parallel with Promise.all, without changing what the route returns, 4) if the work is a long AI generation or similar, show me the pattern to start it in the background and let the page collect the result when it is ready, instead of holding the request open.

Constraints: do not shorten timeouts elsewhere, do not remove functionality to make it faster, and do not switch runtimes (Edge/Node) without explaining what I would gain and lose.

Fix it yourself

Follow the repair

  1. Confirm which route times out and how long it actually runs. In Vercel, open your project's Logs and filter for the failing path, or reproduce the request and watch which call returns the 504. Note the duration Vercel reports — if the function dies at exactly your limit every time, the work simply needs longer than it is allowed. Also test the same route's pieces separately: if the database query or the AI call is slow when run on its own, you have found what the function is waiting on.
  2. Raise the time limit for that route if your plan allows more. In a Next.js route file, one line sets the ceiling for that function:
    // app/api/generate/route.ts
    export const maxDuration = 60; // seconds
    
    export async function POST(req: Request) {
      // your existing handler
    }
    On the Hobby plan, functions default to 10 seconds and can be raised to at most 60. On Pro, you can raise maxDuration up to 300 seconds. Set it on the slow routes only, and treat this as buying headroom, not as the cure — a route that needs the full allowance on every request is a route whose design wants step 3 or 4.
  3. Make the wait itself shorter. Attack whatever the function is waiting on. Run independent calls together instead of in a queue:
    // slow: each call waits for the one before
    const user = await getUser();
    const orders = await getOrders();
    
    // faster: both start at once
    const [user, orders] = await Promise.all([getUser(), getOrders()]);
    For databases: request only the fields and rows you need, add an index for the column you filter or sort by, and check geography — a function running in one region querying a database on another continent pays a travel toll on every single query. In Vercel's project settings you can set the function's region to sit near your database, which is often the single biggest speed-up available.
  4. Move slow work off the request entirely. If the job genuinely takes a minute, no visitor should stand there holding the page open. Change the shape of the feature: the route starts the job, saves a "processing" record, and replies immediately with an ID; the slow work continues in the background (a queue or background-job service such as Inngest, Trigger.dev, or QStash, or a Vercel Cron job for scheduled work); the page checks back — or receives a webhook — and shows the result when it lands. This is how AI generation features survive in production: the request takes a second, the generation takes its time elsewhere.
  5. For AI calls specifically, stream the answer. If you are calling an AI model, return the response as a stream instead of waiting for the complete text before sending anything. The visitor sees words arriving within a second or two, which turns a tense 40-second hang into a responsive page. Streaming does not repeal the clock — the function still has to finish within its maxDuration — so pair it with the raised limit from step 2, and if generations regularly run past even that, move them to the background pattern in step 4.
  6. Know when the real fix is the plan, and when Edge helps. If you are on the Hobby plan and the feature honestly needs more than 60 seconds inside one request, that is a plan ceiling, not a bug: Pro raises the ceiling to 300 seconds. Switching a route to the Edge runtime starts it faster and closer to visitors, but Edge has its own strict CPU limits and no access to some Node features — it suits quick, light work, and it does nothing for a request whose time is spent waiting on a distant database. Pick the tool that matches where your seconds actually go.
Why this happensOptional explanation

Pages on Vercel can be pre-built files, but anything dynamic — an API route, a form handler, a checkout — runs as a function: a small piece of server that wakes up when a request arrives, does its work, and replies. Vercel puts a hard clock on that work. When the clock runs out before the reply is sent, Vercel ends the function and returns 504 FUNCTION_INVOCATION_TIMEOUT to the visitor, sometimes phrased in the logs as "Task timed out after 10 seconds" (or whatever your current limit is).

Functions rarely time out because their own code is slow — your code usually finishes in milliseconds. They time out waiting: on a database query grinding through a big table, on a database on the other side of the world, on three outside calls made one after another, or on an AI model that legitimately needs 30 to 60 seconds to generate an answer. A cold start — the first request after a quiet spell waking a fresh function — adds a second or two on top, which matters when you were already close to the line, but it is almost never the whole story.

  • Slow database work: unindexed queries, huge result sets, or a database far from the function's region add seconds of waiting.
  • Slow outside calls: AI generation and third-party APIs routinely take longer than the default limit allows.
  • Sequential waiting: three calls made one at a time cost the sum of all three; in parallel they cost the slowest one.
  • A plan ceiling: on the Hobby plan the limit is short — 10 seconds by default, raisable to 60 — and no code change makes a 90-second job fit inside it.

Quick answers

How long does Vercel actually give my functions?

On the Hobby plan, functions time out after 10 seconds by default and you can raise that ceiling to 60 seconds. On the Pro plan, you can raise maxDuration up to 300 seconds per function. If your work needs more than your plan's ceiling inside a single request, the fix is to restructure the feature so the slow work happens in the background — not to find a cleverer setting.

Is a cold start causing my timeout?

It contributes a second or two, not tens of seconds. A cold start is just the function waking up — you see it on the first request after a quiet period. If your route regularly dies at the limit, the time is going on waiting for a database or an outside service, and that is where the fix belongs.

Does streaming the response solve an AI timeout?

It makes the wait invisible, not shorter: words start arriving quickly, so the visitor is no longer staring at a spinner. The function still has to finish within its time limit, though, so streaming works alongside a raised maxDuration — and jobs that run for minutes still belong in the background with the page collecting the result afterwards.

One fix, every Friday.

One real error, explained in plain English, with the fix — in your inbox every Friday. No spam, no jargon, unsubscribe anytime.