Vercel: 504 timeout on serverless functions [2026 fix]

Serverless functions exceed 10-second timeout limit. Optimize queries, add streaming, or migrate to long-running endpoints.

TL;DR

Cause: Your serverless function exceeded Vercel's 10-second execution timeout (or 60 seconds on Pro/Enterprise plans).

Fix: Add response streaming, optimize database queries with indexes, or migrate heavy computation to background jobs.

---

Console Error Messages

Here are exact 504 errors you'll see in Vercel logs:

``` Error: FUNCTION_TIMEOUT The function execution time exceeded the maximum allowed duration of 10 seconds. ```

``` HTTP/1.1 504 Gateway Timeout vercel-id: sfo1::h7k8j-1702340400000-abc123def456 ```

``` FetchError: request to https://your-api.vercel.app/api/process failed, reason: socket hang up ```

``` ERR_HTTP_REQUEST_TIMEOUT at Runtime.runHandler Timeout waiting for lambda response after 30000ms ```

``` Function failed due to timeout while waiting for response from database query Query execution time: 15234ms (limit: 10000ms) ```

---

Broken Code vs. Fixed Code

Problem 1: Unoptimized Database Query

BROKEN: ```javascript // api/report.js - Takes 12+ seconds export default async function handler(req, res) { const users = await db.query( 'SELECT * FROM users WHERE created_at > NOW() - INTERVAL 30 DAY' ); const processed = users.map(user => { const transactions = db.query( 'SELECT * FROM transactions WHERE user_id = ?', [user.id] ); return { user, transactions }; }); res.json(processed); } ```

FIXED: ```javascript // api/report.js - Uses indexes + JOIN export default async function handler(req, res) { // Single query with JOIN instead of N+1 const data = await db.query(` SELECT u.*, COUNT(t.id) as transaction_count FROM users u LEFT JOIN transactions t ON u.id = t.user_id WHERE u.created_at > NOW() - INTERVAL 30 DAY GROUP BY u.id `); res.json(data); } ```

Why it works: Eliminates N+1 query problem. One JOIN query executes in ~400ms instead of 50+ sequential queries.

---

Problem 2: Missing Response Streaming

BROKEN: ```javascript // api/export.js - Buffers entire response export default async function handler(req, res) { const allData = await fetchMillion Records(); const csv = convertToCSV(allData); // 8+ seconds res.setHeader('Content-Type', 'text/csv'); res.send(csv); } ```

FIXED: ```javascript // api/export.js - Streams response export default async function handler(req, res) { res.setHeader('Content-Type', 'text/csv'); res.setHeader('Content-Disposition', 'attachment; filename="export.csv"'); const stream = await getDataStream(); stream.pipe(res); }

// Or for Edge Runtime (Vercel's fastest option) export const config = { runtime: 'edge' };

export default async function handler(req) { return new Response(getReadableStream(), { headers: { 'Content-Type': 'text/csv' }, }); } ```

Why it works: Starts sending data immediately instead of buffering. Client receives data while server processes more.

---

Problem 3: Blocking Code in Route Handler

BROKEN: ```javascript // api/webhook.js - Synchronous processing blocks response export default async function handler(req, res) { const payment = req.body; // This takes 8 seconds - response waits await updateInventory(payment.items); await sendEmailReceipts(payment.email); await logAnalytics(payment); res.json({ ok: true }); } ```

FIXED: ```javascript // api/webhook.js - Fire-and-forget with Vercel KV import { kv } from '@vercel/kv';

export default async function handler(req, res) { const payment = req.body; // Return immediately, process asynchronously await kv.lpush('payment-queue', JSON.stringify(payment)); res.json({ ok: true }); }

// cron.js - Separate job processor export const config = { maxDuration: 300, // 5 minutes allowed };

export default async function handler(req, res) { const payment = await kv.lpop('payment-queue'); await updateInventory(payment.items); await sendEmailReceipts(payment.email); await logAnalytics(payment); res.json({ processed: true }); } ```

Why it works: API returns in <100ms. Queue job processes separately with 5-minute timeout.

---

Still Broken? Check These Too

1. Cold start delays: First invocation takes 1-2 seconds. If your function already uses 9 seconds, cold start pushes it over. Solution: Use Vercel's [continuous deployment](/?guide=vercel-cold-starts) with pre-warming or upgrade to Pro plan for faster provisioning.

2. External API timeouts: Your function calls slow third-party APIs (Stripe, Shopify, etc.). Add retry logic with exponential backoff and timeout wrapping: ```javascript const timeout = (promise, ms) => Promise.race([ promise, new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), ms)) ]); ```

3. Memory constraints: Memory pressure slows execution. Check CloudWatch/Vercel logs for "Memory Limit Exceeded." If using Pro, increase allocated memory via vercel.json: ```json { "functions": { "api/**": { "memory": 3008 } } } ```

---

Version Notes

I'm uncertain whether Vercel's Edge Runtime timeout behavior changed between early 2025 and 2026. Edge Functions officially support 30-second timeouts, but regional variations may exist. Check your Vercel dashboard's "Function Metrics" tab to confirm your actual timeout ceiling.

---

Official References:

  • [Vercel Serverless Function Limits](https://vercel.com/docs/functions/serverless-functions#limits)
  • [Vercel Edge Functions Documentation](https://vercel.com/docs/edge-functions)
  • Related Guides:

  • [Optimize database performance](/?guide=postgres-n-plus-one)
  • [Background jobs in Vercel](/?guide=vercel-background-jobs)
  • ---

    Found a different variation? Drop it in the commentsβ€”we're building the 2026 Vercel troubleshooting guide together.

    πŸ”₯ 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