Vercel: 504 timeout on serverless functions [2026 fix]

Serverless functions exceeding 10s timeout or hitting memory limits. Increase function timeout, optimize code, or migrate to Hobby/Pro plan.

TL;DR

Cause: Your serverless function exceeded Vercel's default 10-second timeout or ran out of memory during execution.

Fix: Increase the maxDuration in vercel.json to match your function runtime, or refactor blocking operations into background jobs.

---

Real Console Error Messages

``` Error: FUNCTION_TIMEOUT_EXCEEDED Request exceeded maximum duration of 10s Status Code: 504

FATAL ERROR in v8::OnUnicodeDecodeError Memory allocation failed - JavaScript heap out of memory

ERROR: Task timed out after 900000.00 milliseconds ```

``` WARNING in /var/task/node_modules Maximum call stack size exceeded ```

``` vercel/node: 504 Unknown Error at Object.<anonymous> Request timeout at 10000ms ```

---

The Problem

Vercel's serverless functions have strict execution limits:

  • Hobby plan: 10 second max duration, 128MB memory
  • Pro plan: 60 second max duration, 3008MB memory
  • Enterprise: Up to 900 seconds available
  • When your function takes longer than its allocated maxDuration or tries to allocate more RAM than available, Vercel terminates it and returns a 504 Gateway Timeout.

    ---

    Code: Broken vs. Fixed

    BROKEN: Default 10-second timeout on slow database query

    ```javascript // api/fetch-users.js export default async function handler(req, res) { // No timeout configuration const users = await db.query( 'SELECT * FROM users WHERE status = "active"' ); // This query takes 15 seconds on large datasets res.status(200).json({ users }); } ```

    FIXED: Increase timeout + optimize query

    Option A: Increase maxDuration in vercel.json

    ```json { "functions": { "api/fetch-users.js": { "maxDuration": 30, "memory": 1024 } } } ```

    Option B: Refactor with pagination (RECOMMENDED)

    ```javascript // api/fetch-users.js export default async function handler(req, res) { const page = req.query.page || 1; const pageSize = 50; const offset = (page - 1) * pageSize;

    // Add database indexes on status column const users = await db.query( 'SELECT * FROM users WHERE status = $1 LIMIT $2 OFFSET $3', ['active', pageSize, offset] );

    res.status(200).json({ users, page, pageSize, hasMore: users.length === pageSize }); } ```

    Option C: Move to background job

    ```javascript // api/trigger-user-sync.js (returns immediately) export default async function handler(req, res) { // Trigger background job, don't wait for completion await queue.enqueue('sync-users', {}); res.status(202).json({ status: 'Processing in background' }); }

    // background-jobs/sync-users.js (can run 15+ minutes) import { Queue } from '@vercel/queue';

    export default async function handler(req) { const users = await db.query( 'SELECT * FROM users WHERE status = "active"' ); await cache.set('users', JSON.stringify(users), 3600); } ```

    ---

    Why This Happens

    1. Unoptimized queries: Missing database indexes, N+1 queries, or SELECT * on massive tables 2. Synchronous blocking: setTimeout, fs.readFileSync, or CPU-intensive loops 3. Large payload processing: Parsing 100MB JSON files in memory 4. Dependency bloat: Loading ML libraries that take 8+ seconds to initialize 5. Cold starts + slow operation: First invocation overhead compounds slow database access

    ---

    Version-Specific Notes

    I'm uncertain whether this behavior changed between Vercel CLI versions prior to 2024. If you're using Vercel CLI < 28.0, maxDuration configuration may not be respected—verify your version with vercel --version. Pro plan timeout limits were increased from 60s to 900s in mid-2024 for enterprise customers, but standard Pro remains 60s as of my knowledge cutoff.

    ---

    Still broken? Check these too

    1. Cold start timeout: If the function *starts* timing out after deployment, check for large dependencies. Use vercel env pull && npm ls to audit package size. Solutions: tree-shake unused imports, use dynamic require(), or switch to lighter alternatives (e.g., date-fns instead of moment).

    2. Memory exhaustion without slow operations: Monitor actual memory usage via Vercel logs. If a function under 5 seconds consumes 900MB+ on first run, you likely have a memory leak. Check for: unclosed database connections in global scope, cached objects growing unbounded, or synchronous file reads. Run [related](/guide=memory-profiling) profiling guide.

    3. Timeout only in production, not locally: Local vercel dev doesn't enforce timeouts. Test with vercel deploy --prod to staging first, or use a load testing tool. Related: [debugging production functions](/guide=vercel-logs).

    ---

    References

  • [Vercel Serverless Function Documentation](https://vercel.com/docs/functions/serverless-functions)
  • [maxDuration Configuration](https://vercel.com/docs/functions/serverless-functions/limits)
  • [Vercel Queue for Background Jobs](https://vercel.com/docs/storage/vercel-kv)
  • ---

    Found a different variation? Drop it in the comments—especially if you've solved this on Edge Functions or with specific database drivers.

    🔥 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