Vercel: 504 timeout on serverless functions [2026 fix]
Serverless functions exceed 10s execution limit or cold start delays. Optimize function logic, increase timeout, or split into smaller handlers.
Vercel: 504 timeout on serverless functions [2026 fix]
TL;DR
Cause: Your serverless function is executing longer than Vercel's 10-second timeout limit (Pro plan) or 60-second limit (Enterprise), OR cold starts are pushing you over the edge. Fix: Optimize database queries, implement caching, reduce payload size, or upgrade your Vercel plan for increased timeout allowances.---
Common Error Messages
Here are exact console outputs you'll see at 2am:
``` Error: FUNCTION_TIMEOUT at Runtime.invoke at Timeout._onTimeout [as _callback] (/var/task/node_modules/vercel/index.js:1247:15) at listOnTimeout (internal/timers.js:478:145) ```
``` Vercel Function Error: 504 Gateway Timeout Duration: 10000ms Billed Duration: 10000ms Max Duration Exceeded ```
``` { "errorMessage": "Task timed out after 10.00 seconds", "errorType": "TimeoutError", "stackTrace": ["/var/task/handler.js:45:23"] } ```
``` 502 Bad Gateway Request timeout from upstream service after 30s Vercel serverless execution exceeded maximum duration ```
``` FunctionError: {'type': 'Timeout', 'message': 'The operation exceeded the time limit'} Invoke Error: {'statusCode': 504, 'body': 'Gateway Timeout'} ```
---
Broken Code vs. Fix
Problem 1: Inefficient Database Query
❌ BROKEN:
```javascript
// api/users.js - Makes N+1 queries
export default async function handler(req, res) {
const users = await db.query('SELECT * FROM users');
for (let user of users) {
const orders = await db.query(
SELECT * FROM orders WHERE user_id = ${user.id}
);
user.orders = orders;
}
res.status(200).json(users);
}
```
✅ FIXED: ```javascript // api/users.js - Single JOIN query export default async function handler(req, res) { const users = await db.query(` SELECT u.*, json_agg(o.*) as orders FROM users u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id `); res.status(200).json(users); } ```
Problem 2: Missing Cache Layer
❌ BROKEN: ```javascript // api/analytics.js - Recalculates every request export default async function handler(req, res) { const results = await expensiveAnalyticsCalculation(); res.status(200).json(results); }
async function expensiveAnalyticsCalculation() { // 8+ seconds of processing const data = await fetchDataFromMultipleSources(); return processComplexAggregations(data); } ```
✅ FIXED: ```javascript // api/analytics.js - With caching import { kv } from '@vercel/kv';
export default async function handler(req, res) { const cacheKey = 'analytics:daily'; const cached = await kv.get(cacheKey); if (cached) { return res.status(200).json(JSON.parse(cached)); } const results = await expensiveAnalyticsCalculation(); await kv.setex(cacheKey, 3600, JSON.stringify(results)); res.status(200).json(results); } ```
Problem 3: Synchronous/Serial Operations
❌ BROKEN: ```javascript // api/process.js - Sequential API calls export default async function handler(req, res) { const userAuth = await fetch('https://auth-service.com/verify'); const userData = await fetch('https://user-service.com/profile'); const billing = await fetch('https://billing-service.com/invoice'); res.status(200).json({ userAuth, userData, billing }); } ```
✅ FIXED: ```javascript // api/process.js - Parallel API calls export default async function handler(req, res) { const [userAuth, userData, billing] = await Promise.all([ fetch('https://auth-service.com/verify'), fetch('https://user-service.com/profile'), fetch('https://billing-service.com/invoice') ]); res.status(200).json({ userAuth, userData, billing }); } ```
---
Verification Notes
Timeout behavior varies by Vercel plan:
I cannot guarantee if you're on a custom Enterprise tier without seeing your account settings. Check your [Vercel dashboard](https://vercel.com/dashboard) > Settings > Functions for your specific limits.
---
Still broken? Check these too
1. Cold Start Delays: Vercel isolates are sleeping. Solutions: Use [Vercel Cron](https://vercel.com/docs/cron-jobs) to keep functions warm, or pre-warm with external services (Statuspage, etc.).
2. Unoptimized Dependencies: Large node_modules bloat function bundles. Run npm ls --depth=0 and audit for unused packages. Tree-shake aggressively.
3. Streaming Timeout Mismatch: If using res.write() for streaming, ensure total duration stays under limit. Consider [related streaming guide](/?guide=vercel-streaming).
4. Third-Party Service Slowness: Your function might be waiting on slow upstream APIs. Add explicit timeouts with AbortController to fail fast rather than exhaust the 10s window.
---
Resources
---
Found a different variation? Drop it in the comments. (Does your 504 happen only during cold starts? Different error stack? Share it—let's build a better collective knowledge base.)