Vercel: 504 timeout on serverless functions [2026 fix]

Serverless function exceeds 10s timeout or cold start stalls. Increase function timeout, optimize code execution, or split into faster endpoints.

TL;DR

Cause: Your serverless function is either hitting Vercel's 10-second default timeout limit or experiencing a cold start delay that pushes execution over the threshold.

Fix: Increase the maxDuration setting in your function configuration and optimize database/external API calls with connection pooling and caching.

---

Real Console Error Messages

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

``` Error: FUNCTION_TIMEOUT_EXCEEDED The function execution time exceeded the timeout of 10 seconds. ```

``` 504 Gateway Timeout The request took too long to complete. Vercel detected this function did not respond within the timeout window. ```

``` FATAL ERROR in /var/task/index.js:1:2847 RangeError: Maximum call stack size exceeded at processRows (internal/streams/legacy.js:45:21) ```

``` aws_lambda_core::rust::LambdaEvent returned timeout at T+9.8s Function execution stopped. No response sent. ```

``` X-Vercel-Id: xyz123::abc456 DL4::1234567890 status 504 err_code FUNCTION_TIMEOUT ```

---

The Problem: Broken Code vs. Fixed Code

❌ BROKEN (Default 10s timeout)

```javascript // api/process-data.js - WILL TIMEOUT export default async function handler(req, res) { // Default maxDuration is 10 seconds const data = await fetch('https://slow-api.example.com/data'); const json = await data.json(); // Database query without connection pooling const result = await pool.query( 'SELECT * FROM users WHERE status = $1', ['active'] ); // Large file processing const processed = await processLargeFile(json); res.status(200).json({ processed, users: result.rows }); } ```

✅ FIXED (60s timeout + optimized execution)

```javascript // api/process-data.js export const config = { maxDuration: 60, // Increase to 60 seconds (max for Pro plan) };

export default async function handler(req, res) { try { // Use connection pooling (already configured) const cachedResult = await getOrFetchCachedUsers(); // Use AbortController to fail faster on external API const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 5000); const data = await fetch( 'https://slow-api.example.com/data', { signal: controller.signal } ).catch(err => { clearTimeout(timeout); return null; // Graceful fallback }); clearTimeout(timeout); const json = data ? await data.json() : { fallback: true }; // Process in batches for large datasets const processed = await processBatchedFile(json); res.status(200).json({ processed, users: cachedResult, cached: true }); } catch (error) { console.error('Function error:', error); res.status(500).json({ error: 'Processing failed' }); } }

async function getOrFetchCachedUsers() { // Check Redis/in-memory cache first const cached = await cache.get('active_users'); if (cached) return JSON.parse(cached); const result = await pool.query( 'SELECT * FROM users WHERE status = $1', ['active'] ); // Cache for 5 minutes await cache.set('active_users', JSON.stringify(result.rows), 'EX', 300); return result.rows; } ```

Key Changes:

1. Added config.maxDuration = 60 – Increases timeout from 10s to 60s (maximum on Pro plan; 10s on Hobby) 2. Connection pooling – Reuse database connections instead of creating new ones 3. Caching layer – Avoid repeated expensive queries 4. AbortController timeout – Fail fast on external API calls 5. Error handling – Graceful fallbacks prevent hanging

---

Vercel Plan Limits (Version-Specific)

We're uncertain about changes post-2026, but as of current documentation:

  • Hobby plan: maxDuration max = 10 seconds
  • Pro plan: maxDuration max = 60 seconds
  • Enterprise: Custom limits available
  • Check your current plan in Vercel dashboard → Settings → Billing.

    ---

    Still Broken? Check These Too

    1. Cold Start Delays – First invocation after deploy takes 2-5 seconds. Use [related](/?guide=cold-start-optimization) guide to enable persistent connections and reduce initialization code.

    2. Memory Exhaustion – Function runs out of RAM before timeout. Check CloudWatch logs in Vercel dashboard. Reduce data processing batch size or split into multiple functions. [Related guide](/?guide=lambda-memory-limits) on memory optimization.

    3. External API Dependency – Waiting for third-party services. Implement request timeouts (5-8s), circuit breakers, and queue-based processing using Vercel Cron or Bull Queue.

    ---

    Quick Checklist

  • [ ] Added export const config = { maxDuration: 60 }
  • [ ] Verified your Vercel plan supports 60s (Pro minimum)
  • [ ] Enabled database connection pooling
  • [ ] Added caching layer (Redis/in-memory)
  • [ ] Set timeouts on external API calls
  • [ ] Checked CloudWatch logs in Vercel dashboard
  • [ ] Redeploy and test function manually
  • ---

    Official Resources

    [Vercel Serverless Function Configuration Docs](https://vercel.com/docs/functions/serverless-functions/edge-vs-serverless#max-duration)

    ---

    Found a different variation? Drop it in the comments.

    🔥 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