AI

Claude API Streaming Response Next.js App Router Edge Runtime Timeout Fix

Claude API Streaming Response Next.js App Router Edge Runtime Timeout Fix

Your Claude API streaming works flawlessly on localhost. You push to Vercel. Requests start dying at exactly 10 seconds. That’s not a coincidence — it’s the edge runtime timeout, and it catches nearly every team building AI features in Next.js App Router for the first time.

This piece breaks down why it happens, how the underlying architecture creates the problem, and the specific configuration changes that actually fix it.

Key Takeaways

  • Vercel’s edge runtime enforces a hard 10-second execution timeout. Claude API streaming responses routinely exceed this for complex prompts — 30–90 seconds is common in production.
  • Next.js App Router defaults route handlers to Node.js runtime, but many teams explicitly set runtime = 'edge' for perceived latency benefits, inadvertently triggering timeout failures.
  • Switching to Node.js runtime with export const runtime = 'nodejs' and enabling response streaming via the Web Streams API resolves the timeout for the vast majority of deployments.
  • The Vercel Pro plan raises the Node.js serverless function timeout to 60 seconds; Enterprise allows up to 900 seconds — critical data points when choosing deployment tiers.
  • ReadableStream with TransformStream in App Router route handlers is the correct pattern for Claude API streaming in Next.js App Router as of 2026.

The Architecture Problem Nobody Warns You About

Next.js App Router ships with two distinct execution environments: the Node.js runtime and the edge runtime. They are not interchangeable.

The edge runtime runs on V8 isolates — Vercel uses Cloudflare’s infrastructure for this layer — which means no Node.js APIs, limited CPU time, and a hard 10-second wall clock timeout. No exceptions.

The Node.js serverless runtime is different. According to Vercel’s official platform documentation, the default timeout for serverless functions is 10 seconds on the Hobby plan, 60 seconds on Pro, and configurable up to 900 seconds on Enterprise.

The failure mode plays out predictably. A route handler tagged with export const runtime = 'edge' starts streaming from Claude’s API. The first tokens arrive in 1–2 seconds. The stream looks healthy. At second 10, Vercel’s edge network terminates the connection — mid-response, no error message to the client, just a truncated stream or a hanging request.

Teams spend hours debugging this. The Claude API itself is working fine. The problem lives entirely in the deployment layer.


Why Teams End Up on Edge Runtime Accidentally

Two paths lead to this misconfiguration.

Path 1: Following outdated tutorials. A significant number of Next.js AI integration guides written in 2024 recommended runtime = 'edge' for lower cold start latency. That advice made sense for simple, fast API proxies. It does not hold for LLM streaming, where response time is measured in tens of seconds, not milliseconds.

Path 2: Copying middleware configuration. Middleware in Next.js always runs on the edge runtime — that’s non-negotiable. Teams sometimes copy the runtime export from middleware files into route handlers without realizing they’ve opted into a 10-second ceiling for their AI responses.

The confusion compounds because runtime = 'edge' in a route handler and in middleware look syntactically identical. In middleware, it’s a constraint. In a route handler, it’s a choice — and usually the wrong one.


The Fix: Runtime Switch + Proper Streaming Pattern

Step 1: Change the Runtime Declaration

In your route handler (app/api/chat/route.ts or similar), set:

export const runtime = 'nodejs';
export const maxDuration = 60; // seconds — Pro plan max

Remove any export const runtime = 'edge' line. If there’s no runtime export at all, App Router defaults to Node.js, so you may not need to add anything — but being explicit prevents future accidents.

Step 2: Implement Web Streams Correctly

The Claude API client (@anthropic-ai/sdk) supports streaming via .stream(). The correct pattern for App Router uses ReadableStream from the Web Streams API, which Node.js 18+ supports natively:

import Anthropic from '@anthropic-ai/sdk';
import { NextRequest } from 'next/server';

const client = new Anthropic();

export async function POST(req: NextRequest) {
  const { prompt } = await req.json();

  const stream = new ReadableStream({
    async start(controller) {
      const anthropicStream = await client.messages.stream({
        model: 'claude-opus-4-5',
        max_tokens: 1024,
        messages: [{ role: 'user', content: prompt }],
      });

      for await (const chunk of anthropicStream) {
        if (
          chunk.type === 'content_block_delta' &&
          chunk.delta.type === 'text_delta'
        ) {
          controller.enqueue(new TextEncoder().encode(chunk.delta.text));
        }
      }
      controller.close();
    },
  });

  return new Response(stream, {
    headers: { 'Content-Type': 'text/plain; charset=utf-8' },
  });
}

The stream stays open, tokens flow to the client incrementally, and the 60-second Node.js timeout gives Claude enough runway for complex completions.

Edge vs. Node.js Runtime for AI Streaming

CriteriaEdge RuntimeNode.js Serverless
Max timeout (Vercel Pro)10 seconds60 seconds
Cold start latency~50ms250–500ms
Node.js API support❌ Limited✅ Full
Streaming supportPartial✅ Full Web Streams
Suitable for Claude streaming❌ No✅ Yes
Max timeout (Enterprise)10 seconds900 seconds
Best forAuth checks, redirectsLLM responses, file processing

The cold start difference — 50ms versus roughly 350ms — sounds significant until you remember that Claude responses take 15–45 seconds for anything non-trivial. That edge runtime speed advantage gets completely swamped by actual response duration. You’re optimizing the wrong variable.


Practical Deployment Scenarios

Scenario 1: Short summarization tasks (typically under 8 seconds)

Edge runtime could work here, but it’s fragile. One slow Claude response under load and requests start dying. Node.js runtime is the right call even for fast tasks — the downside risk isn’t worth the marginal cold start improvement.

Scenario 2: Multi-turn chat with large context windows

Responses regularly hit 30–60 seconds. Node.js runtime on Vercel Pro (60-second max) is the minimum viable configuration. For production workloads with p95 response times above 45 seconds, you need Enterprise-tier timeouts or a self-hosted deployment without the Vercel constraint entirely.

Scenario 3: Document analysis or code generation

Responses can reach 90+ seconds for complex tasks. Vercel’s 60-second Pro ceiling becomes the bottleneck. Two options: switch to a container-based deployment — Fly.io, Railway, or AWS ECS — where you control timeouts directly, or break the task into smaller streaming chunks with a progress pattern on the frontend.

The runtime fix works cleanly for scenarios 1 and 2. Scenario 3 requires rethinking the deployment target, not just the runtime configuration. This approach can fail when task complexity consistently pushes past 60 seconds — no amount of configuration tuning on Vercel Pro will save you there.


What to Expect in the Next 6–12 Months

The edge runtime timeout issue is well-documented enough that Vercel will likely address it more directly. A few things worth tracking:

Vercel’s AI Gateway product (in beta as of Q1 2026) promises managed streaming with extended timeouts — potentially removing the need for custom route handler patterns entirely.

Anthropic’s streaming API continues to evolve. The claude-opus-4-5 model’s median time-to-first-token has dropped measurably since mid-2025, which improves edge runtime viability for short prompts specifically.

Next.js 15.x is adding more granular timeout controls per-route, expected to land in Q2–Q3 2026 based on the open RFC.


Four things worth locking in before you ship anything:

  • Edge runtime is wrong for LLM streaming. Node.js runtime is right. This isn’t a close call.
  • export const maxDuration = 60 is required on Vercel Pro. Without it, you get the 10-second default even on Node.js runtime.
  • Web Streams API (ReadableStream) is the correct abstraction. Node.js stream.Readable doesn’t map cleanly to Next.js App Router’s response model.
  • Container deployments remove the timeout ceiling entirely for long-running tasks — worth the added operational complexity if your use case demands it.

The fix takes about 10 minutes once you know what’s wrong. The hard part is diagnosing that the edge runtime is the culprit in the first place.

Now you know where to look.

References

  1. Routing: API Routes | Next.js
  2. How to Fix ‘API Route’ Timeout Errors in Next.js

Photo by Vitaly Gariev on Unsplash