Vercel: 504 timeout on serverless functions [2026 fix]

Serverless function exceeds 10s timeout limit or cold start + slow initialization. Reduce function execution time or increase timeout configuration.

TL;DR

Cause: Your Vercel serverless function is either executing longer than the 10-second default timeout or experiencing a cold start delay combined with slow code initialization.

Fix: Implement function timeout configuration in vercel.json and optimize hot paths in your handler code.

---

Real Console Error Messages

Here are exact error outputs you'll see at 2am:

``` Error: FUNCTION_TIMEOUT - The function "/api/process-data" did not complete within the timeout period. Request ID: arn:aws:lambda:us-east-1:123456789:function:process-data-abc123 ```

``` Fatal error in handler: Task timed out after 10.00 seconds 504 Gateway Timeout Vercel FaaS execution timeout exceeded ```

``` Error: Lambda execution timed out (duration: 10003ms, max: 10000ms) STDOUT: [Function started] [Database query initiated...] [WARNING: Execution halted] ```

``` vercel[api]: Execution ID: ixyz789 vercel[api]: Duration: 10004ms vercel[api]: Status Code: 504 vercel[api]: Error: Timeout waiting for lambda response ```

``` POST /api/users HTTP/1.1 HTTP/1.1 504 Gateway Timeout Content-Type: application/json {"error":"Function execution timeout","code":"FUNCTION_TIMEOUT"} ```

---

Broken Code vs. Fixed Code

❌ BROKEN: No timeout configuration + synchronous database call

```javascript // api/process-data.js export default async function handler(req, res) { // Cold start + synchronous operations = timeout const db = require('pg'); const client = new db.Client({ connectionString: process.env.DATABASE_URL }); await client.connect(); // Takes 2-3 seconds on cold start const result = await client.query( 'SELECT * FROM large_table WHERE id IN (' + Array(1000).fill('$1').join(',') + ')' ); // Potentially 8+ seconds res.json(result.rows); } ```

Problem: No timeout override (defaults to 10s), synchronous initialization, and potentially slow query = guaranteed 504 at scale.

✅ FIXED: Timeout configuration + connection pooling + optimized query

Step 1: Add vercel.json configuration

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

Step 2: Refactor handler with connection pooling

```javascript // api/process-data.js import { Pool } from 'pg';

// Initialize pool OUTSIDE handler (reuse across warm invocations) const pool = new Pool({ connectionString: process.env.DATABASE_URL, max: 2 });

export default async function handler(req, res) { try { // Use pooled connection (milliseconds, not seconds) const result = await pool.query( 'SELECT id, name FROM large_table WHERE id = ANY($1) LIMIT 100', [req.body.ids] ); res.status(200).json(result.rows); } catch (error) { res.status(500).json({ error: error.message }); } } ```

Why this works:

  • maxDuration: 30 gives 30-second timeout (covers cold starts)
  • Connection pool initialized outside handler (reused on warm invocations)
  • Parameterized query with LIMIT clause prevents large result sets
  • Reduced memory allocations
  • Note: Vercel's timeout limits vary by plan. We're uncertain about specific Pro/Enterprise tier limits in 2026—consult official docs for your current plan.

    ---

    Still Broken? Check These Too

    1. Cold Start + Missing Dependencies Cache - Solution: Use vercel/python or vercel/go (faster cold starts) instead of Node.js for CPU-intensive work. Or pre-warm functions with scheduled invocations using [cron triggers](/?guide=vercel-cron-monitoring).

    2. Database Connection Limits Exhausted - Solution: Set aggressive connection timeout and implement circuit breaker. Use pool.connect() with 3-second timeout wrapper to fail fast instead of hanging until the 10s limit.

    3. Third-Party API Calls Without Timeout - Solution: Wrap all external HTTP requests with explicit timeouts: ```javascript const response = await fetch(externalAPI, { signal: AbortSignal.timeout(5000) }); ```

    ---

    Additional Optimization Tips

  • Use Streaming Responses: For large payloads, stream data instead of buffering:
  • ```javascript res.setHeader('Content-Type', 'application/json'); res.write('{"data": ['); // stream items res.end(']}'); ```
  • Implement Request Queuing: If multiple requests spike, queue them in Redis/Bull rather than processing all at once.
  • Monitor Cold Start Metrics: Check Vercel Analytics dashboard for function duration baseline.
  • ---

    Documentation & References

  • [Vercel Serverless Function Limits](https://vercel.com/docs/functions/serverless-functions#limits)
  • Related guide: [Debugging Vercel function performance](/?guide=vercel-performance-profiling)
  • ---

    Found a different variation? Drop it in the comments—whether it's a specific database driver issue, edge runtime timeout quirks, or ISR-related timeouts, your 2am fix might save someone else's deployment. 🚀

    🔥 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