withSseHeartbeat()
Wraps a server-sent events Response so it emits periodic : heartbeat comments while the underlying stream is idle. Proxies and load balancers often close connections that send no bytes for a while, which drops responses during long reasoning bursts or slow tool calls.
Use this when you build the response yourself with handleChatStream(), handleWorkflowStream(), or handleNetworkStream(). chatRoute() applies the same wrapper internally through its heartbeatMs option.
Usage exampleDirect link to Usage example
Next.js App Router example:
import { handleChatStream, withSseHeartbeat } from '@mastra/ai-sdk'
import { createUIMessageStreamResponse } from 'ai'
import { mastra } from '@/src/mastra'
export async function POST(req: Request) {
const params = await req.json()
const stream = await handleChatStream({
mastra,
agentId: 'weatherAgent',
version: 'v7',
params,
})
return withSseHeartbeat(createUIMessageStreamResponse({ stream }), 15000)
}
Wrap the response after it has been encoded. handleChatStream() returns a stream of UI message chunks, and heartbeats are raw SSE comments that only exist once those chunks are serialized to the wire format.
ParametersDirect link to Parameters
response:
heartbeatMs?:
0 or less to disable heartbeats.ReturnsDirect link to Returns
A Response that streams the source body with heartbeat comments inserted during idle periods. The input response is returned unchanged when heartbeatMs is omitted, is 0 or less, or the response has no body.
BehaviorDirect link to Behavior
- Heartbeats are only inserted between complete SSE frames, so a partially delivered frame is never split.
- Source data, stream completion, and stream errors always take priority over a due heartbeat.
- Canceling the wrapped response cancels the source stream and clears the pending heartbeat timer.
- A
RangeErroris thrown when heartbeats are enabled with a value that can't be scheduled with a timer, meaning a non-finite number or a value greater than2147483647. UseassertValidHeartbeatMs()to apply the same check to user-supplied configuration before you start streaming.