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.
Advanced · Stopping StreamsRead docs ↗

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.
  • onAbort saves the partial answer.
  • Frees the function and the provider slot.

Cons

  • On Vercel, enable supportsCancellation per function.
  • Abort breaks stream resumption (resume: true).
  • Jobs that must finish anyway should ignore the signal.