Vercel: 504 timeout on serverless functions [2026 fix]
Serverless function exceeds 10s timeout or cold-start delay. Increase function timeout, optimize code, or split into smaller functions.
Vercel: 504 timeout on serverless functions [2026 fix]
TL;DR
Cause: Your serverless function runs longer than Vercel's 10-second default timeout (or hits cold-start delays on infrequent invocations). Fix: IncreasemaxDuration in vercel.json to 60 seconds, optimize database queries, or implement request queuing.---
Exact Console Error Messages
Here are real error outputs you'll see at 2am:
``` Error: FUNCTION_TIMEOUT at Runtime.withTimeout at Timeout._onTimeout [as _callback] (/var/task/handler.js:145:23) Code: ERR_FUNCTION_TIMEOUT ```
``` HTTP 504 Gateway Timeout vercel-cli: Function exceeded maximum execution time of 10s ```
``` { "errorCode": "FUNCTION_INVOCATION_TIMEOUT", "message": "Your function execution exceeded the time limit of 10 seconds.", "requestId": "req_xyz123" } ```
``` WARN: Cold start took 8234ms. Total execution: 12450ms. Result: 504 ```
``` [ERROR] Invoke Error FunctionName: api-handler Duration: 10002ms Billed Duration: 10000ms DurationExceeded: true ```
---
Broken Code vs. Fixed Code
Problem #1: Default Timeout Too Low
❌ BROKEN: ```javascript // api/process-data.js export default async function handler(req, res) { const data = await fetchLargeDataset(); const processed = await expensiveOperation(data); // takes 15 seconds await saveToDatabase(processed); res.status(200).json({ success: true }); } ```
✅ FIXED: ```json // vercel.json { "functions": { "api/process-data.js": { "maxDuration": 60 } } } ```
Then your function runs unmodified—Vercel now allows up to 60 seconds.
Problem #2: Inefficient Database Queries
❌ BROKEN: ```javascript // api/users.js export default async function handler(req, res) { const userIds = await db.query('SELECT id FROM users'); // N+1 problem for (const user of userIds) { const profile = await db.query('SELECT * FROM profiles WHERE user_id = ?', [user.id]); const posts = await db.query('SELECT * FROM posts WHERE user_id = ?', [user.id]); // Loop runs 1000 times, each with 2 queries = 2000+ queries } res.json(userIds); } ```
✅ FIXED: ```javascript // api/users.js export default async function handler(req, res) { // Single query with JOIN const data = await db.query(` SELECT u.id, u.name, p.profile_data, COUNT(po.id) as post_count FROM users u LEFT JOIN profiles p ON u.id = p.user_id LEFT JOIN posts po ON u.id = po.user_id GROUP BY u.id `); res.json(data); } ```
Problem #3: Blocking Operations on Main Thread
❌ BROKEN: ```javascript // api/resize-image.js export default async function handler(req, res) { const image = await downloadImage(req.body.url); // 8 seconds const resized = await resizeSync(image, 1920, 1080); // 5 seconds, blocks await uploadS3(resized); // 3 seconds res.json({ done: true }); } ```
✅ FIXED: ```javascript // api/resize-image.js export default async function handler(req, res) { const image = await downloadImage(req.body.url); // Queue heavy work asynchronously queueTask('resize-image', { imageId: image.id, dimensions: [1920, 1080] }).catch(err => console.error(err)); // Return immediately res.status(202).json({ taskId: image.id }); }
// In a separate background job handler export async function resizeWorker(task) { const image = await getImageFromCache(task.imageId); const resized = await resizeAsync(image, ...task.dimensions); await uploadS3(resized); } ```
Note on version-specific behavior: The maxDuration field has been stable since Vercel 2.0 (2023), but Pro/Enterprise plans may support up to 300 seconds. Standard hobby plans cap at 60 seconds. Check your Vercel dashboard → Settings → Function execution timeout to confirm your plan's limit.
---
Still broken? Check these too
1. Cold Start Delays: Functions invoked after 15+ minutes of inactivity add 2-8 seconds overhead. Solution: Ping your function every 5 minutes with a health check, or use [Vercel's autoscaling guide](/?guide=vercel-cold-starts).
2. Slow External APIs: If you're calling third-party APIs (Stripe, OpenAI, etc.) without timeout controls, a single slow upstream service blocks your entire function. Add timeout: 5000 to fetch calls.
3. Memory Pressure: Functions allocated 128MB can hit garbage collection pauses. Increase to 1024MB+ in vercel.json under memory field (Pro plan required). Check [Vercel memory optimization](/?guide=serverless-memory).
---
Official Resources
---
Found a different variation? Drop it in the comments below—include the exact error message and your fix so we can help others at 3am.