Vercel: 504 timeout on serverless functions [2026 fix]
Serverless function exceeds 10s timeout or cold start delay. Optimize code, increase timeout, or split into faster functions.
Vercel: 504 Timeout on Serverless Functions [2026 Fix]
TL;DR
Cause: Your serverless function is exceeding Vercel's 10-second timeout limit (or 60s on Pro/Enterprise), usually from slow database queries, external API calls, or heavy processing. Fix: Reduce execution time by optimizing queries, implementing caching, or increasing your plan's timeout threshold.---
Real Console Error Messages
Here are EXACT error messages you'll see at 2am:
``` 504: GATEWAY_TIMEOUT Error: Function execution took longer than the specified timeout duration of 10 seconds ```
``` Error: Task timed out after 10.00 seconds at Runtime.invokeFunction [as handler] (runtime.js:1234:5) ```
``` VercelFunctionError: FUNCTION_TIMEOUT_EXCEEDED Function exceeded maximum duration of 10s ```
``` [ERROR] 2026-01-15T02:34:12.456Z undefined ERROR Timeout waiting for response from /api/users - waited 10000ms ```
``` GatewayTimeout: The request to the function timed out after 10 seconds. This usually indicates the function is performing too much work. ```
---
Broken Code vs. Fixed Code
❌ BROKEN: Database Query Without Connection Pooling
```javascript // api/users.js - SLOW (causes 504) export default async function handler(req, res) { // Creates new connection for EVERY request const client = new Client({ connectionString: process.env.DATABASE_URL }); await client.connect(); // ~500-2000ms cold start const result = await client.query( 'SELECT * FROM users WHERE status = $1', ['active'] ); await client.end(); res.json(result.rows); } ```
✅ FIXED: Connection Pooling + Query Optimization
```javascript // api/users.js - FAST import { Pool } from 'pg';
const pool = new Pool({ connectionString: process.env.DATABASE_URL, max: 1 // Optimal for serverless });
export default async function handler(req, res) { try { // Reuses existing connection const result = await pool.query( 'SELECT id, name FROM users WHERE status = $1 LIMIT 100', ['active'] ); res.setHeader('Cache-Control', 'public, s-maxage=60'); res.json(result.rows); } catch (error) { res.status(500).json({ error: error.message }); } } ```
Key changes:
Pool to module level (reused across invocations)❌ BROKEN: Slow External API Without Timeout
```javascript // api/fetch-data.js export default async function handler(req, res) { const data = await fetch('https://external-api.com/huge-dataset'); const json = await data.json(); res.json(json); // If API hangs >10s = 504 } ```
✅ FIXED: Timeout + Streaming Response
```javascript // api/fetch-data.js export default async function handler(req, res) { const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 8000); // 8s limit try { const data = await fetch('https://external-api.com/huge-dataset', { signal: controller.signal }); const json = await data.json(); clearTimeout(timeout); res.json(json); } catch (error) { clearTimeout(timeout); res.status(503).json({ error: 'External service timeout' }); } } ```
---
Timeout Limits by Vercel Plan
| Plan | Timeout | Cost Impact | |------|---------|-------------| | Hobby | 10s | Free | | Pro | 60s | $20/month | | Enterprise | 900s | Custom |
Version note: These limits apply to Vercel Functions as of 2026. If behavior differs, explicitly check your account settings under Settings → Functions.
---
Step-by-Step Fix Checklist
1. Check function execution time → Vercel Dashboard → Logs → filter by duration
2. Add response caching → Use s-maxage header (see fixed code above)
3. Implement database pooling → Use PgBouncer or connection pool library
4. Set abort timeout on external calls → 8-9 seconds max
5. Upgrade plan if needed → Hobby → Pro for 60s timeout
6. Split large operations → Move heavy processing to background jobs ([Background Jobs Best Practices](/?guide=vercel-cron-jobs))
---
Still Broken? Check These Too
1. Cold start delays → Your function is taking >2s just to initialize. Check bundle size (vercel build --debug). Move heavy dependencies outside handlers.
2. Memory exhaustion → Function runs out of RAM before timeout. Add logging to track memory usage. Consider increasing function memory in vercel.json if available on your plan.
3. Cascading timeouts → Your function calls another serverless function that also times out. Add timeout guards at each level and implement circuit breakers with exponential backoff.
---
Documentation & Resources
---
Found a different variation? Drop it in the comments
This covers the most common 504 causes, but Vercel's infrastructure is constantly updated. If you're hitting timeouts from a scenario not listed here (unusual framework behavior, regional latency, etc.), share the exact error logs below—community fixes help everyone.