Fix: 504 Gateway Timeout in Vercel Serverless Functions
The Symptom
Your API route (like an AI generation script, email sender, or heavy database query) works perfectly on your local machine. However, when deployed to Vercel, the browser hangs for exactly 10 to 15 seconds before crashing with this error:
504: GATEWAY_TIMEOUT
Code: FUNCTION_INVOCATION_TIMEOUT
The serverless function has exceeded its execution limit.
The Cure
Vercel places strict execution time limits on Serverless Functions to prevent runaway costs. You must explicitly request a longer execution time (up to your plan's maximum allowed limit).
Cure 1: Next.js App Router & API Routes
Export the maxDuration constant at the top of your specific route file.
// Allow this specific route to run for up to 60 seconds
export const maxDuration = 60;
export async function POST(request) {
// Your long-running AI task or heavy DB query here
const result = await heavyTask();
return new Response(JSON.stringify(result), { status: 200 });
}
Cure 2: Pure Vanilla / vercel.json
If you are not using Next.js, define the limits in your vercel.json file at the root of your project.
{
"functions": {
"api/long-task.js": {
"maxDuration": 60
}
}
}
The Breakdown
Localhost does not have a hard timeout. A script can run for 5 minutes locally without failing. Vercel, however, kills hanging serverless functions to free up compute resources based on your billing tier:
- Hobby Plan: Default 10s. Maximum limit you can request is 10s (in older versions) or 60s (in updated 2024+ limits).
- Pro Plan: Default 15s. Maximum limit you can request is 300s (5 minutes).
If you set maxDuration = 300 while on the Hobby tier, your Vercel deployment will fail during the build process.
Prevention & Advanced Architectures
If your task regularly exceeds 60 seconds (like processing large video files or heavy AI generation), standard Serverless Functions are the wrong architecture. Consider these alternatives:
-
Streaming (Edge Runtime): If using AI (like OpenAI), switch your route to
export const runtime = 'edge'and stream the response. Streaming keeps the connection alive indefinitely, bypassing the 504 timeout error. -
Background Jobs: Offload the task using a message queue like Upstash QStash, or use Vercel's
after()hook, so your API route instantly returns a 200 OK while the heavy lifting happens asynchronously.
Loading logs...