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

Streaming responses from Claude work beautifully in local dev. Then you deploy to Vercel, hit the 10-second edge function timeout, and watch your chatbot die mid-sentence. This pattern has become one of the most-searched deployment issues in 2026 for teams building AI features on Next.js.
Key Takeaways
- Vercel’s Edge Runtime enforces a hard 10-second execution timeout by default — a limit Claude’s streaming responses routinely blow past for any non-trivial prompt.
- Next.js App Router’s Route Handlers support streaming via the Web Streams API, but only when correctly configured with
runtime = 'edge'and proper response headers.- Switching to Node.js runtime in App Router removes the 10-second cap entirely, at the cost of cold-start latency — typically 200–800ms longer than edge cold starts.
- Fixing Claude API streaming in the Next.js App Router requires a deliberate runtime decision, not just a config tweak.
- Teams that implement
maxDurationalongside streaming see a 90%+ reduction in mid-stream timeout failures, according to Vercel’s platform documentation (2026).
1. Why This Problem Exists Right Now
Next.js App Router shipped with two distinct runtimes: Edge and Node.js. Edge runs on Vercel’s globally distributed network — fast, cheap, constrained. Node.js runs on traditional serverless functions — slightly slower to start, but with dramatically higher execution limits.
Claude’s API responses, especially for summarization or multi-step reasoning tasks, stream tokens over 15–45 seconds depending on prompt complexity. That blows straight past Vercel’s default 10-second edge timeout.
App Router made this worse, not better. The old Pages Router api/ directory had clearer timeout documentation. App Router’s route.ts handlers introduced new streaming primitives — ReadableStream, TransformStream — without making the runtime trade-offs obvious upfront.
What’s changed in 2026: Anthropic’s Claude 3.5 and 3.7 models generate longer, more structured outputs than earlier versions. Average response lengths for claude-3-5-sonnet in production have increased roughly 30% compared to Claude 2, per Anthropic’s usage benchmarks published Q1 2026. More tokens mean longer streams. Longer streams mean more timeout collisions.
The point is direct: fixing Claude streaming timeouts in Next.js App Router isn’t one fix — it’s a decision tree with three viable paths, each carrying real trade-offs.
2. Background: How App Router Streaming Actually Works
Next.js App Router uses the Web Streams API natively. A route.ts file returning a Response with a ReadableStream body will stream chunks to the client as they arrive — no buffering, no waiting for completion.
Claude’s Node.js SDK (@anthropic-ai/sdk) exposes streaming via stream() or .stream() on message creation, returning an async iterable. Bridging that to a ReadableStream is straightforward:
const stream = await anthropic.messages.stream({ ... });
const readable = new ReadableStream({
async start(controller) {
for await (const chunk of stream) {
controller.enqueue(new TextEncoder().encode(chunk.toString()));
}
controller.close();
}
});
return new Response(readable, {
headers: { 'Content-Type': 'text/event-stream' }
});
The code above works. The runtime configuration around it is where teams get burned.
Next.js App Router defaults to Node.js runtime for route handlers, but many teams explicitly set export const runtime = 'edge' chasing global latency wins. That single line changes everything — you’re now under Vercel’s Edge Runtime constraints, capping execution at 10 seconds on Hobby and 25 seconds on Pro.
According to Vercel’s Edge Runtime documentation, the maximum duration on Edge is 25 seconds on Pro plans. Claude’s longer responses can still exceed this. Node.js serverless functions on Vercel Pro support up to 300 seconds with explicit maxDuration configuration.
3. Main Analysis
The Three Runtime Paths for Claude Streaming
Picking the right runtime for your use case is the core decision. No universal answer exists, but the data makes the trade-offs clear.
Path 1: Stay on Edge, work within limits. If your Claude prompts are short and responses average under 20 seconds, edge works. Set aggressive max_tokens limits (512–1024) and accept the constraint. Response latency to global users will be 30–60ms faster on edge versus Node.js serverless, per Vercel’s own benchmarks.
Path 2: Switch to Node.js runtime with maxDuration. Remove export const runtime = 'edge' from your route handler and add export const maxDuration = 60 (or higher). This is the fix most teams need. Cold starts add roughly 200ms globally, but you gain 60–300 seconds of execution time depending on your Vercel plan.
Path 3: Use a hybrid architecture. Keep edge for fast, non-streaming routes. Route all Claude streaming requests through a dedicated Node.js handler. This is what Vercel’s own AI templates — including ai-chatbot — do as of their Q1 2026 updates: a separate app/api/chat/route.ts running Node.js runtime while static and non-AI routes stay on edge.
Comparison: Edge vs. Node.js Runtime for Claude Streaming
| Criteria | Edge Runtime | Node.js Runtime |
|---|---|---|
| Default timeout | 10s (Hobby), 25s (Pro) | Configurable, up to 300s (Pro) |
| Cold start latency | ~50–100ms | ~200–800ms |
| Global distribution | Yes (runs at edge PoPs) | No (regional only) |
| Claude streaming support | Partial (short responses only) | Full |
maxDuration config | Not supported | Supported |
| Vercel plan requirement | Available on all plans | Available on all plans |
| Best for | Short AI responses, <15s | Long AI responses, chat, summarization |
The table makes Path 2 look obvious — and for most Claude use cases, it is. But don’t dismiss edge entirely. For Claude-powered features like autocomplete or one-line summaries, edge’s latency advantage is real and measurable.
The maxDuration Configuration
This is the most commonly missed part. Switching runtime alone doesn’t extend your timeout. Both changes are required:
// app/api/claude/route.ts
export const runtime = 'nodejs'; // explicit, or just remove the edge declaration
export const maxDuration = 120; // seconds — requires Vercel Pro for >60s
export async function POST(req: Request) {
// Claude streaming logic here
}
Without maxDuration, Node.js serverless functions on Vercel still default to 10 seconds. According to Vercel’s serverless function configuration docs, the default is 10 seconds across both runtimes unless explicitly overridden.
The fix that actually works in production combines three things: correct runtime, explicit maxDuration, and proper streaming headers.
Response Headers Matter More Than You’d Think
Edge and Node.js runtimes handle response flushing differently. For Server-Sent Events (SSE) patterns — which most Claude streaming implementations use — you need explicit headers:
return new Response(readable, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache, no-transform',
'X-Accel-Buffering': 'no',
}
});
X-Accel-Buffering: no targets Vercel’s nginx layer specifically. Without it, chunks get buffered and the client sees nothing until the stream completes — which defeats the entire purpose of streaming. This affects both runtimes but gets forgotten most often when migrating from edge to Node.js.
4. Practical Implications: Three Scenarios, Three Fixes
Scenario 1: Chatbot timing out on Vercel Hobby plan.
The 10-second edge limit isn’t configurable on Hobby. Switch to Node.js runtime with maxDuration = 60. If 60 seconds still isn’t enough for very long Claude responses, upgrading to Pro is the only path — Hobby caps Node.js functions at 60 seconds regardless.
Scenario 2: Pro plan, edge runtime, 25s timeout still insufficient.
Switch to Node.js runtime and set maxDuration = 300. That supports responses up to five minutes. Realistically, if Claude is taking that long, prompt engineering is the bigger problem — but the ceiling is there when you need it.
Scenario 3: Self-hosted Next.js (not Vercel).
The timeout problem shifts. Node.js HTTP servers don’t have Vercel’s artificial limits. The risk moves to gateway timeouts from nginx or AWS ALB — typically 60–120 seconds by default. Set proxy_read_timeout 300; in your nginx config and match it with maxDuration in your Next.js config.
What to watch in Q3–Q4 2026:
- Vercel’s AI-specific function tier, announced in their March 2026 roadmap, promises dedicated streaming infrastructure with higher default timeouts.
- Anthropic’s streaming API latency improvements for Claude 3.7 Sonnet — their Q1 2026 technical blog referenced ongoing work to reduce time-to-first-token by roughly 40%.
- Next.js 15.x’s planned streaming improvements for App Router, specifically around backpressure handling in
ReadableStream.
This approach can fail when prompts are poorly scoped and responses routinely exceed even 300 seconds — at that point, the architecture itself needs rethinking, not just the timeout config. And switching to Node.js runtime isn’t always the answer: for globally distributed apps where latency to end users is the primary metric, the 200–800ms cold start penalty on Node.js is a real cost worth quantifying before committing.
5. Conclusion & What’s Next
The fix comes down to three decisions: runtime, duration config, and headers. Get all three right and Claude streaming works reliably in production.
- Edge runtime is wrong for most Claude streaming. 25 seconds isn’t enough for serious AI workloads.
maxDurationis mandatory. A runtime switch alone doesn’t extend your timeout.X-Accel-Buffering: noprevents silent buffering that kills the streaming UX before users notice anything useful.- Node.js runtime with
maxDuration = 120covers 95%+ of real-world Claude use cases.
Over the next six months, expect Vercel’s platform to get better at AI workloads natively. But App Router configuration issues won’t self-resolve — these runtime decisions need to be made deliberately, not discovered in production logs at 2am.
The immediate action: audit every route.ts touching Claude’s API. Check for runtime = 'edge'. Check for missing maxDuration. Check your response headers. That audit takes 20 minutes and will catch the issue before your users do.
What’s your current timeout configuration for Claude streaming? The answer shapes which fix actually applies to your setup.
References
Photo by Bernd 📷 Dittrich on Unsplash


