Vercel: 504 timeout on serverless functions [2026 fix]

Serverless function exceeds 10s timeout or cold start memory spike. Increase function timeout, optimize initialization code, and enable streaming responses.

Vercel: 504 timeout on serverless functions [2026 fix]

TL;DR

Cause: Your serverless function exceeds Vercel's 10-second default timeout or runs out of memory during cold starts. Fix: Set maxDuration in vercel.json, optimize imports outside request handlers, and use streaming for long operations.

---

Exact Error Messages from Console

``` Error: FUNCTION_INVOCATION_TIMEOUT The Serverless Function exceeded the 10s timeout specified. Please check that your code completes. ```

``` ERROR: 504 Gateway Timeout The server did not respond within the specified time period. ```

``` WARN: Cold Start took 8234ms Function duration: 5000ms Total: 13234ms (exceeded 10000ms limit) ```

``` Error: Task timed out after 900 seconds RESET /api/export - 504 ```

``` FATAL ERROR: CALL_SNAPSHOT_FAILURE Unable to restore function snapshot within timeout window. ```

---

Code: Before vs. After

❌ BROKEN CODE

api/export.js (slow import + no timeout config) ```javascript // ❌ Importing heavy libraries at module level const pdf = require('pdfkit'); const sharp = require('sharp'); const crypto = require('crypto');

export default async function handler(req, res) { // Process takes 15+ seconds const document = new pdf.PDFDocument(); for (let i = 0; i < 1000; i++) { const processed = await sharp(imageBuffer) .resize(800, 600) .toBuffer(); document.image(processed); } res.setHeader('Content-Type', 'application/pdf'); res.send(document); } ```

vercel.json (missing timeout config) ```json { "version": 2, "builds": [{"src": "api/**/*.js", "use": "@vercel/node"}] } ```

---

✅ FIXED CODE

api/export.js (lazy imports + streaming) ```javascript // ✅ Import heavy libraries INSIDE handler to delay cold start export default async function handler(req, res) { const pdf = require('pdfkit'); const sharp = require('sharp'); // ✅ Set response headers for streaming res.setHeader('Content-Type', 'application/pdf'); const document = new pdf.PDFDocument(); document.pipe(res); // ✅ Process in smaller batches to avoid memory spike for (let i = 0; i < 1000; i++) { if (i % 100 === 0) { // Yield to event loop every 100 items await new Promise(resolve => setImmediate(resolve)); } const processed = await sharp(imageBuffer) .resize(800, 600) .toBuffer(); document.image(processed); } document.end(); } ```

vercel.json (timeout + memory config) ```json { "version": 2, "functions": { "api/export.js": { "maxDuration": 60, "memory": 3008 } }, "builds": [{"src": "api/**/*.js", "use": "@vercel/node"}] } ```

---

Why This Works

1. maxDuration: 60 – Extends timeout from default 10s to 60s (Pro plans support up to 900s; we're uncertain if this changed in 2026, check official docs).

2. Lazy imports – Moving require() inside handlers delays library loading, reducing cold start time counted against your timeout window.

3. Streaming response – Using .pipe(res) sends data progressively instead of buffering the entire PDF in memory.

4. memory: 3008 – Allocates maximum memory (3GB on Pro) to prevent out-of-memory kills during processing.

5. Event loop yields – setImmediate() prevents V8 from blocking on large loops, letting Node.js handle other operations.

---

Still broken? Check these too

1. Database Query Timeouts

If your API calls a database, add explicit query timeouts: ```javascript const result = await db.query(sql, { timeout: 5000 }); // 5s per query ``` See [database connection pooling guide](/?guide=database-timeouts) for details.

2. External API Calls Hanging

Third-party APIs may not respond quickly. Add fetch timeouts: ```javascript const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 8000); const res = await fetch(url, { signal: controller.signal }); ``` Related: [external API integration patterns](/?guide=api-calls).

3. Memory Leaks in Loops

Declare variables inside loops to prevent accumulation: ```javascript for (let i = 0; i < items.length; i++) { const item = items[i]; // ✅ New scope per iteration // ... process item } ```

---

Official Resources

  • Vercel Functions Timeout Limits: https://vercel.com/docs/functions/serverless-functions#timeout
  • maxDuration Configuration: https://vercel.com/docs/functions/configuring-functions/timeout
  • Node.js Memory Management: https://nodejs.org/en/docs/guides/simple-profiling/
  • ---

    Quick Checklist

  • [ ] Added maxDuration to vercel.json
  • [ ] Moved heavy require() statements inside handlers
  • [ ] Implemented streaming for large responses
  • [ ] Added timeouts to database and fetch calls
  • [ ] Checked function logs in Vercel Dashboard → Deployments → Function Logs
  • [ ] Verified memory isn't spiking (check Metrics tab)
  • ---

    Found a different variation? Drop it in the comments—we update this guide based on real production incidents.

    🔥 0d
    LIVE
    ↓ PlanetScale rage spiking •⚠ Vercel pricing complaints •↑ Railway gaining fast •↑ Supabase happiness rising •↑ Resend loved by devs •↓ PlanetScale rage spiking •⚠ Vercel pricing complaints •↑ Railway gaining fast •↑ Supabase happiness rising
    DEVELOPER PAIN RADAR // Loading...

    Developers complain.
    Opportunities appear.

    We track what developers are struggling with today — and what opportunities that creates.

    —
    guides today
    —
    avg happiness
    🔥 Pain
    📖 Guides
    🔭 Explore
    👤 Mine
    🔥 Pain Radar — rage scores today
    ↗ share
    💡 Opportunity Feed — pain = market gap
    📈 Tool Momentum
    all scores →
    📖 Latest Guide
    all guides →
    📖 All Guides
    📊 Tool Scores
    + Submit
    📰 Hacker News
    ➕ Submit a Tool
    ← back