Vercel: 504 timeout on serverless functions [2026 fix]
Serverless function exceeds 10s timeout limit or cold start + slow initialization. Reduce function execution time or increase timeout configuration.
TL;DR
Cause: Your Vercel serverless function is either executing longer than the 10-second default timeout or experiencing a cold start delay combined with slow code initialization.
Fix: Implement function timeout configuration in vercel.json and optimize hot paths in your handler code.
---
Real Console Error Messages
Here are exact error outputs you'll see at 2am:
``` Error: FUNCTION_TIMEOUT - The function "/api/process-data" did not complete within the timeout period. Request ID: arn:aws:lambda:us-east-1:123456789:function:process-data-abc123 ```
``` Fatal error in handler: Task timed out after 10.00 seconds 504 Gateway Timeout Vercel FaaS execution timeout exceeded ```
``` Error: Lambda execution timed out (duration: 10003ms, max: 10000ms) STDOUT: [Function started] [Database query initiated...] [WARNING: Execution halted] ```
``` vercel[api]: Execution ID: ixyz789 vercel[api]: Duration: 10004ms vercel[api]: Status Code: 504 vercel[api]: Error: Timeout waiting for lambda response ```
``` POST /api/users HTTP/1.1 HTTP/1.1 504 Gateway Timeout Content-Type: application/json {"error":"Function execution timeout","code":"FUNCTION_TIMEOUT"} ```
---
Broken Code vs. Fixed Code
❌ BROKEN: No timeout configuration + synchronous database call
```javascript // api/process-data.js export default async function handler(req, res) { // Cold start + synchronous operations = timeout const db = require('pg'); const client = new db.Client({ connectionString: process.env.DATABASE_URL }); await client.connect(); // Takes 2-3 seconds on cold start const result = await client.query( 'SELECT * FROM large_table WHERE id IN (' + Array(1000).fill('$1').join(',') + ')' ); // Potentially 8+ seconds res.json(result.rows); } ```
Problem: No timeout override (defaults to 10s), synchronous initialization, and potentially slow query = guaranteed 504 at scale.
✅ FIXED: Timeout configuration + connection pooling + optimized query
Step 1: Add vercel.json configuration
```json { "functions": { "api/process-data.js": { "maxDuration": 30, "memory": 1024 } } } ```
Step 2: Refactor handler with connection pooling
```javascript // api/process-data.js import { Pool } from 'pg';
// Initialize pool OUTSIDE handler (reuse across warm invocations) const pool = new Pool({ connectionString: process.env.DATABASE_URL, max: 2 });
export default async function handler(req, res) { try { // Use pooled connection (milliseconds, not seconds) const result = await pool.query( 'SELECT id, name FROM large_table WHERE id = ANY($1) LIMIT 100', [req.body.ids] ); res.status(200).json(result.rows); } catch (error) { res.status(500).json({ error: error.message }); } } ```
Why this works:
maxDuration: 30 gives 30-second timeout (covers cold starts)LIMIT clause prevents large result setsNote: Vercel's timeout limits vary by plan. We're uncertain about specific Pro/Enterprise tier limits in 2026—consult official docs for your current plan.
---
Still Broken? Check These Too
1. Cold Start + Missing Dependencies Cache
- Solution: Use vercel/python or vercel/go (faster cold starts) instead of Node.js for CPU-intensive work. Or pre-warm functions with scheduled invocations using [cron triggers](/?guide=vercel-cron-monitoring).
2. Database Connection Limits Exhausted
- Solution: Set aggressive connection timeout and implement circuit breaker. Use pool.connect() with 3-second timeout wrapper to fail fast instead of hanging until the 10s limit.
3. Third-Party API Calls Without Timeout - Solution: Wrap all external HTTP requests with explicit timeouts: ```javascript const response = await fetch(externalAPI, { signal: AbortSignal.timeout(5000) }); ```
---
Additional Optimization Tips
---
Documentation & References
---
Found a different variation? Drop it in the comments—whether it's a specific database driver issue, edge runtime timeout quirks, or ISR-related timeouts, your 2am fix might save someone else's deployment. 🚀