Vercel: 504 timeout on serverless functions [2026 fix]

Serverless function exceeds 10s timeout or cold starts delay response. Increase function timeout, optimize code, or upgrade plan.

Vercel: 504 Timeout on Serverless Functions – Production Fix Guide

TL;DR

Cause: Your serverless function is either exceeding Vercel's 10-second default timeout, experiencing cold starts, or hitting resource limits on your plan. Fix: Increase the maxDuration setting in vercel.json, optimize database queries, or upgrade to Pro plan for longer timeouts.

---

Real Console Error Messages

Here are the exact errors you'll see at 2am:

``` 504 Gateway Timeout vercel-cli: Function execution took too long ```

``` ERROR: Function timed out after 10 seconds at Runtime.invokeAsync (/var/task/handler.js:1:1) ```

``` DynoTimeout: Execution timed out after 10000ms Response status: 504 X-Vercel-Error: FUNCTION_INVOCATION_TIMEOUT ```

``` aws_lambda_core.InvokeEndpointError: Failed to invoke endpoint HTTP 504: Gateway Timeout ```

``` ERROR [Function] query took 12500ms, exceeds timeout window StatusCode: 504 ErrorMessage: The function did not complete before the timeout was reached ```

---

The Problem: Broken Code Example

Your current vercel.json or API route:

```json { "functions": { "api/data.js": { "memory": 512 } } } ```

```javascript // api/data.js - TIMES OUT export default async (req, res) => { const results = await db.query( SELECT * FROM large_table WHERE status = 'pending' ); const processed = await expensiveTransformation(results); const final = await anotherSlowOperation(processed); res.json(final); }; ```

Why it breaks:

  • Vercel Hobby/Pro plans default to 10-second timeout
  • Three sequential await calls compound delays
  • No pagination on large_table query
  • Cold start adds 2-5 seconds on first invocation
  • No error handling if operations exceed limits
  • ---

    The Fix: Side-by-Side Comparison

    FIXED vercel.json:

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

    FIXED api/data.js:

    ```javascript export default async (req, res) => { // Set 25s timeout for Node.js operation (5s buffer for Vercel overhead) const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 25000);

    try { // PAGINATE: only fetch what's needed const limit = req.query.limit || 100; const offset = req.query.offset || 0; const results = await db.query( SELECT * FROM large_table WHERE status = $1 LIMIT $2 OFFSET $3, ['pending', limit, offset], { signal: controller.signal } );

    // PARALLEL: run independent operations together const [processed, cached] = await Promise.all([ expensiveTransformation(results), cacheService.get('metadata') ]);

    clearTimeout(timeout); res.json({ data: processed, meta: cached }); } catch (error) { clearTimeout(timeout); if (error.name === 'AbortError') { return res.status(504).json({ error: 'Request timeout - try with smaller limit' }); } res.status(500).json({ error: error.message }); } }; ```

    Key changes: 1. maxDuration: 30 → Increases timeout to 30s (Pro+ plan required) 2. memory: 1024 → More RAM reduces cold start time 3. Added pagination (LIMIT/OFFSET) → Fetch only needed rows 4. Promise.all() → Parallel instead of sequential operations 5. AbortController → Gracefully handle timeout client-side 6. try/catch → Return 504 instead of silent failure

    ---

    Important Version Notes

    We're uncertain about: Vercel's exact cold-start behavior changed between 2024-2026; if you're on a plan from before Q2 2025, maxDuration values above 30s may require enterprise contact. Check your actual Vercel dashboard plan limits.

    ---

    Still Broken? Check These Too

    1. Database Connection Pool Exhausted If using Postgres/MySQL, your connection pool may be full. Add pool: { max: 10 } to your connection config and ensure you're calling client.end() in function cleanup.

    2. Cold Start Delays (First Invocation) Upgrade to Pro ($20/mo) for guaranteed warm containers, or use [Vercel Cron Jobs](/?guide=vercel-cron) to ping functions every 5 minutes to keep them warm.

    3. External API Calls Hanging If calling third-party APIs without timeouts, they may hang indefinitely. Wrap external calls with Promise.race([apiCall, timeoutPromise]) or use axios timeout: 8000 option.

    ---

    Deploy & Monitor

    ```bash

    Push changes

    git add vercel.json api/data.js git commit -m "fix: increase timeout and optimize queries" git push

    Monitor in real-time

    vercel logs --follow ```

    Watch your Vercel dashboard Logs tab for X-Vercel-Duration header—if consistently near 30s, you need to optimize further, not just increase timeout.

    ---

    Official Resources

  • [Vercel Serverless Function Configuration Docs](https://vercel.com/docs/concepts/functions/serverless-functions)
  • [Vercel Edge Functions vs. Serverless Functions](https://vercel.com/docs/concepts/functions/edge-functions)
  • ---

    Found a different variation? Drop it in the comments—504s can hide multiple root causes and we'll add your fix to the guide.

    🔥 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