ai newsFr., 6. Nov.
EilmeldungOpenAI is stepping back from NDAs for data center projects

Your Next.js AI streaming route keeps billing you after the user leaves

An AI chat endpoint feels finished the moment tokens start streaming into the browser. Then your first real bill arrives, and the token count is higher than what your users actually read. The usual reason: responses that keep generating after the user has already closed the tab. Where the money lea

dev.toDonnerstag 23:54 · 05.11.2 Min. Lesezeit
Bild: dev.to

Posted on Nov 5 • Originally published at shipwrightkit.com

An AI chat endpoint feels finished the moment tokens start streaming into the browser. Then your first real bill arrives, and the token count is higher than what your users actually read. The usual reason: responses that keep generating after the user has already closed the tab.

In the Next.js App Router, a streaming route opens a connection to the model and pipes tokens back to the browser. If the user navigates away or closes the tab mid-response, the browser drops its connection — but the upstream request to the model keeps generating to completion. You pay for every token it produces, and nobody ever sees them. On long answers with an impatient audience, that waste adds up fast.

When you build the SSE stream yourself with a ReadableStream, its cancel() callback fires the moment the client connection drops. That's your hook to abort the upstream model request instead of letting it run to completion:

export function POST ( req: Request ) { const upstream = anthropic. messages. stream ({ model, max_tokens, messages }); const body = new ReadableStream ({ async start ( controller ) { for await ( const event of upstream ) controller. enqueue ( encode ( event )); controller. close (); }, cancel () { // The browser went away — stop generating (and paying). upstream. abort (); }, }); return new Response ( body, { headers: { " content-type ": " text/event-stream ", " cache-control ": " no-cache, no-transform ", }, }); } Enter fullscreen mode Exit fullscreen mode That one method turns "streaming works in the demo" into "streaming doesn't leak money in production."

None of this is hard. But it's the kind of thing you only discover you needed after it has already cost you — which is exactly why it should live in the foundation of an AI app, not the backlog.

I package this pattern — along with per-request cost metering, typed tool use, versioned prompts with an eval harness, and plan-gated quotas — into a Next.js 16 + Claude starter kit called Shipwright. The live demo shows the exact cost of every request as you chat.

Quelle: dev.to (dev.to). Original öffnen