Vercel: 504 timeout on serverless functions [2026 fix]
Serverless function exceeds 10s timeout or cold starts delay response. Increase function timeout, optimize code, or upgrade plan.
Vercel: 504 Timeout on Serverless Functions – Production Fix Guide
TL;DR
Cause: Your serverless function is either exceeding Vercel's 10-second default timeout, experiencing cold starts, or hitting resource limits on your plan. Fix: Increase themaxDuration setting in vercel.json, optimize database queries, or upgrade to Pro plan for longer timeouts.---
Real Console Error Messages
Here are the exact errors you'll see at 2am:
``` 504 Gateway Timeout vercel-cli: Function execution took too long ```
``` ERROR: Function timed out after 10 seconds at Runtime.invokeAsync (/var/task/handler.js:1:1) ```
``` DynoTimeout: Execution timed out after 10000ms Response status: 504 X-Vercel-Error: FUNCTION_INVOCATION_TIMEOUT ```
``` aws_lambda_core.InvokeEndpointError: Failed to invoke endpoint HTTP 504: Gateway Timeout ```
``` ERROR [Function] query took 12500ms, exceeds timeout window StatusCode: 504 ErrorMessage: The function did not complete before the timeout was reached ```
---
The Problem: Broken Code Example
Your current vercel.json or API route:
```json { "functions": { "api/data.js": { "memory": 512 } } } ```
```javascript
// api/data.js - TIMES OUT
export default async (req, res) => {
const results = await db.query(
SELECT * FROM large_table WHERE status = 'pending'
);
const processed = await expensiveTransformation(results);
const final = await anotherSlowOperation(processed);
res.json(final);
};
```
Why it breaks:
await calls compound delayslarge_table query---
The Fix: Side-by-Side Comparison
FIXED vercel.json:
```json { "functions": { "api/data.js": { "memory": 1024, "maxDuration": 30 } } } ```
FIXED api/data.js:
```javascript export default async (req, res) => { // Set 25s timeout for Node.js operation (5s buffer for Vercel overhead) const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 25000);
try {
// PAGINATE: only fetch what's needed
const limit = req.query.limit || 100;
const offset = req.query.offset || 0;
const results = await db.query(
SELECT * FROM large_table WHERE status = $1 LIMIT $2 OFFSET $3,
['pending', limit, offset],
{ signal: controller.signal }
);
// PARALLEL: run independent operations together const [processed, cached] = await Promise.all([ expensiveTransformation(results), cacheService.get('metadata') ]);
clearTimeout(timeout); res.json({ data: processed, meta: cached }); } catch (error) { clearTimeout(timeout); if (error.name === 'AbortError') { return res.status(504).json({ error: 'Request timeout - try with smaller limit' }); } res.status(500).json({ error: error.message }); } }; ```
Key changes:
1. maxDuration: 30 → Increases timeout to 30s (Pro+ plan required)
2. memory: 1024 → More RAM reduces cold start time
3. Added pagination (LIMIT/OFFSET) → Fetch only needed rows
4. Promise.all() → Parallel instead of sequential operations
5. AbortController → Gracefully handle timeout client-side
6. try/catch → Return 504 instead of silent failure
---
Important Version Notes
We're uncertain about: Vercel's exact cold-start behavior changed between 2024-2026; if you're on a plan from before Q2 2025, maxDuration values above 30s may require enterprise contact. Check your actual Vercel dashboard plan limits.
---
Still Broken? Check These Too
1. Database Connection Pool Exhausted
If using Postgres/MySQL, your connection pool may be full. Add pool: { max: 10 } to your connection config and ensure you're calling client.end() in function cleanup.
2. Cold Start Delays (First Invocation) Upgrade to Pro ($20/mo) for guaranteed warm containers, or use [Vercel Cron Jobs](/?guide=vercel-cron) to ping functions every 5 minutes to keep them warm.
3. External API Calls Hanging
If calling third-party APIs without timeouts, they may hang indefinitely. Wrap external calls with Promise.race([apiCall, timeoutPromise]) or use axios timeout: 8000 option.
---
Deploy & Monitor
```bash
Push changes
git add vercel.json api/data.js git commit -m "fix: increase timeout and optimize queries" git pushMonitor in real-time
vercel logs --follow ```Watch your Vercel dashboard Logs tab for X-Vercel-Duration header—if consistently near 30s, you need to optimize further, not just increase timeout.
---
Official Resources
---
Found a different variation? Drop it in the comments—504s can hide multiple root causes and we'll add your fix to the guide.