Stop means stop
Forward req.signal so Stop also ends the model call.
AI SDK docsai-sdk.dev
The AI SDK functions have an abortSignal argument that you can use to cancel a stream.
From ai-sdk and the Stopping Streams docs.
Stop the client, or the model
Press Generate, then Stop mid-answer.
Signal not forwardedBad
Serveridle
Shown 0 tokensBilled 0 tokens
streamText({ model, messages })Forwards req.signalGood
Serveridle
Shown 0 tokensBilled 0 tokens
streamText({ …, abortSignal: req.signal })// app/api/chat/route.ts
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
const result = streamText({
model: 'anthropic/claude-sonnet-5',
messages: await convertToModelMessages(messages),
abortSignal: req.signal, // client stop() aborts the model call
onAbort: async ({ steps }) => {
await savePartial(steps); // keep what was already generated
},
});
return createUIMessageStreamResponse({
stream: toUIMessageStream({ stream: result.stream }),
});
}
// app/page.tsx
const { status, stop } = useChat();
<button onClick={stop} disabled={!(status === 'streaming' || status === 'submitted')}>
Stop
</button>
Why it matters, pros and cons
Why it matters
stop() only aborts the fetch. Unless the route forwards the signal, the model keeps writing and you keep paying.
Pros
- No tokens billed after the reader gave up.
onAbortsaves the partial answer.- Frees the function and the provider slot.
Cons
- On Vercel, enable
supportsCancellationper function. - Abort breaks stream resumption (
resume: true). - Jobs that must finish anyway should ignore the signal.