Vercel: 504 timeout on serverless functions [2026 fix]
Serverless functions exceeding 10s timeout or hitting memory limits. Increase function timeout, optimize code, or migrate to Hobby/Pro plan.
TL;DR
Cause: Your serverless function exceeded Vercel's default 10-second timeout or ran out of memory during execution.
Fix: Increase the maxDuration in vercel.json to match your function runtime, or refactor blocking operations into background jobs.
---
Real Console Error Messages
``` Error: FUNCTION_TIMEOUT_EXCEEDED Request exceeded maximum duration of 10s Status Code: 504
FATAL ERROR in v8::OnUnicodeDecodeError Memory allocation failed - JavaScript heap out of memory
ERROR: Task timed out after 900000.00 milliseconds ```
``` WARNING in /var/task/node_modules Maximum call stack size exceeded ```
``` vercel/node: 504 Unknown Error at Object.<anonymous> Request timeout at 10000ms ```
---
The Problem
Vercel's serverless functions have strict execution limits:
When your function takes longer than its allocated maxDuration or tries to allocate more RAM than available, Vercel terminates it and returns a 504 Gateway Timeout.
---
Code: Broken vs. Fixed
BROKEN: Default 10-second timeout on slow database query
```javascript // api/fetch-users.js export default async function handler(req, res) { // No timeout configuration const users = await db.query( 'SELECT * FROM users WHERE status = "active"' ); // This query takes 15 seconds on large datasets res.status(200).json({ users }); } ```
FIXED: Increase timeout + optimize query
Option A: Increase maxDuration in vercel.json
```json { "functions": { "api/fetch-users.js": { "maxDuration": 30, "memory": 1024 } } } ```
Option B: Refactor with pagination (RECOMMENDED)
```javascript // api/fetch-users.js export default async function handler(req, res) { const page = req.query.page || 1; const pageSize = 50; const offset = (page - 1) * pageSize;
// Add database indexes on status column const users = await db.query( 'SELECT * FROM users WHERE status = $1 LIMIT $2 OFFSET $3', ['active', pageSize, offset] );
res.status(200).json({ users, page, pageSize, hasMore: users.length === pageSize }); } ```
Option C: Move to background job
```javascript // api/trigger-user-sync.js (returns immediately) export default async function handler(req, res) { // Trigger background job, don't wait for completion await queue.enqueue('sync-users', {}); res.status(202).json({ status: 'Processing in background' }); }
// background-jobs/sync-users.js (can run 15+ minutes) import { Queue } from '@vercel/queue';
export default async function handler(req) { const users = await db.query( 'SELECT * FROM users WHERE status = "active"' ); await cache.set('users', JSON.stringify(users), 3600); } ```
---
Why This Happens
1. Unoptimized queries: Missing database indexes, N+1 queries, or SELECT * on massive tables
2. Synchronous blocking: setTimeout, fs.readFileSync, or CPU-intensive loops
3. Large payload processing: Parsing 100MB JSON files in memory
4. Dependency bloat: Loading ML libraries that take 8+ seconds to initialize
5. Cold starts + slow operation: First invocation overhead compounds slow database access
---
Version-Specific Notes
I'm uncertain whether this behavior changed between Vercel CLI versions prior to 2024. If you're using Vercel CLI < 28.0, maxDuration configuration may not be respected—verify your version with vercel --version. Pro plan timeout limits were increased from 60s to 900s in mid-2024 for enterprise customers, but standard Pro remains 60s as of my knowledge cutoff.
---
Still broken? Check these too
1. Cold start timeout: If the function *starts* timing out after deployment, check for large dependencies. Use vercel env pull && npm ls to audit package size. Solutions: tree-shake unused imports, use dynamic require(), or switch to lighter alternatives (e.g., date-fns instead of moment).
2. Memory exhaustion without slow operations: Monitor actual memory usage via Vercel logs. If a function under 5 seconds consumes 900MB+ on first run, you likely have a memory leak. Check for: unclosed database connections in global scope, cached objects growing unbounded, or synchronous file reads. Run [related](/guide=memory-profiling) profiling guide.
3. Timeout only in production, not locally: Local vercel dev doesn't enforce timeouts. Test with vercel deploy --prod to staging first, or use a load testing tool. Related: [debugging production functions](/guide=vercel-logs).
---
References
---
Found a different variation? Drop it in the comments—especially if you've solved this on Edge Functions or with specific database drivers.