Vercel: 504 timeout on serverless functions [2026 fix]
Serverless functions exceed 10s execution limit or memory threshold. Optimize code, increase timeout, or split into smaller functions.
Vercel: 504 timeout on serverless functions [2026 fix]
TL;DR
Cause: Your serverless function exceeds Vercel's 10-second execution timeout (Pro plan) or 60-second limit (Enterprise), or hits memory constraints during execution. Fix: Optimize database queries, implement caching, reduce payload size, or migrate long-running tasks to background jobs using Vercel Cron or external workers.---
Real Console Error Messages
Here are exact errors you'll see in Vercel logs:
``` 504: DEADLINE_EXCEEDED FunctionName: api/process-data Duration: 10245ms Error: The function execution time has exceeded the timeout. ```
``` ERROR [api/export-report]: Task timed out after 10000ms Invocation failed: Gateway timeout Request ID: fnc_abc123xyz789 ```
``` {"errorCode":"FUNCTION_TIMEOUT","message":"Serverless function timed out","duration":"10s","maxDuration":"10s","functionName":"api/process-large-dataset"} ```
``` aws_lambda_runtime.api.InvocationError: Task timed out after 10000 milliseconds Stack trace from execution: at Timeout._onTimeout [as _callback] ```
``` Error: ECONNRESET at TCPConnectWrap.afterConnect [as oncomplete] Hangup detected: Function did not respond within 10000ms ```
---
Broken Code vs. Fixed Code
Problem 1: Synchronous Database Loop (BROKEN)
```javascript
// ❌ BROKEN - Queries database 1000 times sequentially
export default async function handler(req, res) {
const userIds = req.body.ids; // array of 1000 IDs
let results = [];
for (let id of userIds) {
// Each query takes ~10ms, total = 10 seconds
const user = await db.query(SELECT * FROM users WHERE id = ${id});
results.push(user);
}
res.json(results);
}
```
FIXED: Batch Queries with Connection Pooling
```javascript
// ✅ FIXED - Batches queries, uses pooling, completes in ~200ms
export default async function handler(req, res) {
const userIds = req.body.ids;
// Use parameterized batch query
const results = await db.query(
SELECT * FROM users WHERE id = ANY($1),
[userIds]
);
res.json(results);
}
```
---
Problem 2: Missing Response Timeout (BROKEN)
```javascript // ❌ BROKEN - External API never responds, hangs forever export default async function handler(req, res) { const response = await fetch('https://external-api.com/data'); const data = await response.json(); res.json(data); } ```
FIXED: Add Explicit Timeout
```javascript // ✅ FIXED - Timeout after 5 seconds export default async function handler(req, res) { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 5000); try { const response = await fetch('https://external-api.com/data', { signal: controller.signal, timeout: 5000 }); clearTimeout(timeoutId); const data = await response.json(); res.json(data); } catch (error) { res.status(504).json({ error: 'Upstream timeout' }); } } ```
---
Problem 3: Processing Large Files Synchronously (BROKEN)
```javascript // ❌ BROKEN - Loads entire 50MB file into memory export default async function handler(req, res) { const file = await fs.readFile('/tmp/large-export.csv', 'utf-8'); const lines = file.split('\n'); const processed = lines.map(line => expensiveTransform(line)); res.json(processed); } ```
FIXED: Stream Processing
```javascript // ✅ FIXED - Streams file, processes chunks export default async function handler(req, res) { const stream = fs.createReadStream('/tmp/large-export.csv'); const results = []; return new Promise((resolve) => { stream.on('data', chunk => { results.push(expensiveTransform(chunk)); }); stream.on('end', () => { res.json(results); resolve(); }); }); } ```
---
Configuration: Vercel.json Timeout Setting
Note on version behavior: As of 2026, Vercel's timeout limits depend on your plan. Pro plans receive 10 seconds; Enterprise can negotiate. We cannot definitively state if future plans will extend this—check official docs for your tier.
```json { "functions": { "api/long-process.js": { "maxDuration": 60 } } } ```
⚠️ Caveat: Pro plan functions cannot exceed 10s regardless of maxDuration setting. Only Enterprise deployments honor longer values.
---
Still broken? Check these too
1. Cold Start Overhead – First invocation takes 2-3s. Add [HTTP keep-alive](/?guide=vercel-cold-starts) to reduce initial delays. Verify in Vercel dashboard Duration vs. Init Duration metrics.
2. Database Connection Limits – Each function spawn creates new connections. Implement [connection pooling](/?guide=database-pooling) with PgBouncer or similar.
3. Memory Exhaustion – Functions default to 1GB RAM. Monitor via console.log(process.memoryUsage()). Offload to background jobs using Vercel Cron or Bull queue.
---
Official Resources
---
Found a different variation? Drop it in the comments—we'll add it to this guide.