Vercel: 504 timeout on serverless functions [2026 fix]
Serverless functions exceed 10s timeout or hit memory limits. Optimize function execution time and reduce payload size immediately.
Vercel: 504 timeout on serverless functions [2026 fix]
TL;DR
Cause: Your serverless function exceeded Vercel's 10-second timeout or ran out of memory before responding. Fix: Add execution timeout configuration, optimize database queries, and stream large responses instead of buffering them.---
Real Console Error Messages
``` Error: FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 1: 0x7f1234567890 node::Abort() [node] 2: 0x7f1234567890 node::OnFatalError(char const*, char const*) [node] ```
``` 504: GATEWAY_TIMEOUT The request took too long to process and timed out. Deadline exceeded or the function did not respond within the timeout window. ```
``` Error: TimeoutError: KnexTimeoutError at Timeout._onTimeout (/var/task/node_modules/knex/lib/client.js:234:15) Database query exceeded 10000ms timeout ```
``` FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - Reached heap limit Allocation failed - JavaScript heap out of memory ```
``` ERR! error Command failed with exit code 139. ERR! signal: SEGV ERR! signal: Segmentation fault Memory exhausted during function execution ```
---
Broken Code vs. Fix
Problem 1: No Timeout Configuration
❌ BROKEN: ```javascript // api/slow-endpoint.js export default async function handler(req, res) { const data = await db.query('SELECT * FROM users WHERE status = ?', ['active']); const processed = data.map(user => complexCalculation(user)); res.json(processed); } ```
✅ FIXED: ```javascript // api/slow-endpoint.js export const config = { maxDuration: 30, // Vercel Pro: up to 900s, default 10s };
export default async function handler(req, res) { res.setHeader('Content-Type', 'application/json'); const data = await db.query( 'SELECT id, name FROM users WHERE status = ? LIMIT 100', ['active'], { timeout: 5000 } // Database timeout before function timeout ); const processed = data.map(user => complexCalculation(user)); res.json(processed); } ```
Key changes:
maxDuration config (requires Vercel Pro plan for >30s)Problem 2: Unbuffered Large Responses
❌ BROKEN: ```javascript // api/export-data.js export default async function handler(req, res) { const allUsers = await db.query('SELECT * FROM users'); // Could be millions const csv = convertToCSV(allUsers); // Entire string in memory res.setHeader('Content-Type', 'text/csv'); res.send(csv); } ```
✅ FIXED: ```javascript // api/export-data.js export const config = { maxDuration: 60, };
export default async function handler(req, res) {
res.setHeader('Content-Type', 'text/csv');
res.setHeader('Content-Disposition', 'attachment; filename="users.csv"');
const batchSize = 1000;
let offset = 0;
let isFirst = true;
while (true) {
const batch = await db.query(
'SELECT id, name, email FROM users ORDER BY id LIMIT ? OFFSET ?',
[batchSize, offset]
);
if (batch.length === 0) break;
const csvBatch = batch.map(row =>
${row.id},${row.name},${row.email}
).join('\n');
if (isFirst) {
res.write('id,name,email\n');
isFirst = false;
}
res.write(csvBatch + '\n');
offset += batchSize;
}
res.end();
}
```
Key changes:
res.write() instead of buffering---
Version-Specific Notes
Uncertainty: Vercel's serverless timeout limits vary by plan. As of 2026, default is 10 seconds for Hobby plan, 60 seconds for Pro, up to 900 seconds for Enterprise. The exact timeout values may have changed—verify current limits at [Vercel Docs](https://vercel.com/docs/functions/serverless-functions/runtimes#max-duration).
Node.js versions: Memory limits depend on runtime. We cannot guarantee exact memory allocations across all Node.js LTS versions (18, 20, 22) as Vercel updates these regularly.
---
Still broken? Check these too
1. [Cold Start Issues](/?guide=vercel-cold-start) — First invocation slower than usual. Check if function initializes connections outside handler. Move expensive setup inside handler with caching.
2. [Dependency Size Bloat](/?guide=vercel-bundle-size) — Large node_modules = longer execution time. Run npm ls to find heavy packages. Replace with lightweight alternatives (e.g., date-fns instead of moment).
3. Database Connection Pooling — Each function invocation spawns new connection. Use connection pools (PrismaORM's built-in pooling, or pg-boss for queues) to reuse connections across cold starts.
---
Found a different variation? Drop it in the comments
If you encountered a different root cause (middleware timeout, middleware chain timeouts, Redis connection hangs, Lambda layer issues), share your exact error and solution in the comments to help other 2am responders.
---
References: