Vercel: 504 timeout on serverless functions [2026 fix]
Serverless functions exceed 10s default timeout or memory limits; increase timeout in vercel.json and optimize cold starts.
Vercel: 504 timeout on serverless functions [2026 fix]
TL;DR
Cause: Your serverless function exceeded Vercel's 10-second execution timeout (or 60s for Pro plans) or ran out of memory during initialization. Fix: Addfunctions.maxDuration to vercel.json and optimize cold start performance.---
Exact Error Messages from Console
Here are the real errors you'll see:
``` Error: FUNCTION_INVOCATION_TIMEOUT The function "api/users" failed to respond within the timeout period. ```
``` FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 1: 0x55f2c8c node::Abort() [node] 2: 0x55f2c8c node::OnFatalError(char const*, char const*) [node] ```
``` <504> <h1>Gateway Timeout</h1> <p>The request could not be processed by the endpoint within the allotted time.</p> ```
``` WARNING in ./api/expensive-calculation.js Module size exceeds recommended limit (4.5 MB) ```
``` error: function execution took 12847ms, max timeout is 10000ms ```
---
Broken Code vs. Fixed Code
Problem 1: Missing timeout configuration
BROKEN: ```json // vercel.json - NO timeout specified { "buildCommand": "npm run build", "outputDirectory": ".next" } ```
FIXED: ```json // vercel.json - explicit timeout for long-running functions { "buildCommand": "npm run build", "outputDirectory": ".next", "functions": { "api/**/*.js": { "maxDuration": 30 }, "api/heavy-processing.js": { "maxDuration": 60, "memory": 3008 } } } ```
Problem 2: Unoptimized function with slow initialization
BROKEN: ```javascript // api/users.js - connects to DB on every invocation const mongoose = require('mongoose'); const heavyLibrary = require('heavy-ml-lib');
export default async function handler(req, res) { // Connection happens EVERY TIME (cold start penalty) await mongoose.connect(process.env.DB_URL); const result = await heavyLibrary.process(req.body); res.json(result); } ```
FIXED: ```javascript // api/users.js - reuse connections + lazy load let cachedDb = null;
const connectDb = async () => { if (cachedDb) return cachedDb; const mongoose = require('mongoose'); const conn = await mongoose.connect(process.env.DB_URL); cachedDb = conn; return conn; };
export default async function handler(req, res) { // Connection reused across invocations await connectDb(); // Lazy load heavy library only when needed const heavyLibrary = require('heavy-ml-lib'); const result = await heavyLibrary.process(req.body); res.status(200).json(result); }
export const config = { maxDuration: 45, memory: 3008 }; ```
Problem 3: Memory misconfiguration
BROKEN: ```javascript // Attempting 5GB operation with default 1024MB export default async function handler(req, res) { const largeBuffer = Buffer.alloc(1024 * 1024 * 800); // 800MB const anotherBuffer = Buffer.alloc(1024 * 1024 * 300); // OOM error - exceeds 1GB default } ```
FIXED: ```javascript export default async function handler(req, res) { const largeBuffer = Buffer.alloc(1024 * 1024 * 500); const anotherBuffer = Buffer.alloc(1024 * 1024 * 300); res.json({ success: true }); }
export const config = { maxDuration: 30, memory: 3008 // Upgraded to 3GB for memory-intensive work }; ```
---
Version-Specific Behavior Notes
I'm uncertain about: Whether custom Node.js versions beyond 20.x show different timeout behavior in 2026 environments. Test in staging if using non-standard runtime versions.
Confirmed constants:
---
Still broken? Check these too
1. [Database Connection Pooling Issues](/?guide=connection-pool-exhaustion) — If you're hitting DB max connections alongside timeouts, implement connection pooling with pg or database-specific connection managers.
2. [Cold Start Optimization](/?guide=vercel-cold-starts) — Minify dependencies, use tree-shaking, and consider splitting functions. Large bundle sizes = longer cold starts = timeout risk.
3. External API Rate Limits or Slow Webhooks — Your 504 might be a timeout waiting for a third-party service. Add explicit fetch timeouts: fetch(url, { timeout: 5000 }) to fail fast.
---
Next Steps
1. Deploy the vercel.json changes to production
2. Monitor cold start metrics in Vercel Dashboard (Functions tab)
3. If still failing, check Vercel Function Logs for the exact execution time
4. Consider splitting heavy operations into multiple smaller functions
Official Docs: [Vercel Functions Configuration](https://vercel.com/docs/functions/serverless-functions/runtimes#maxduration)
Found a different variation? Drop it in the comments—we update this guide based on real 2am incidents.