Applied AI
LangGraph stream heartbeats can outlast a client timeout
Set an end-to-end progress deadline for agent streams that stay open on SSE heartbeats.
October 31, 2026
A live connection is not necessarily a progressing run. A LangGraph SDK issue reproduces runs.stream() remaining open past a configured timeout= while an SSE server sends comment-only heartbeats. The reporter's local fixture produces no result events; the heartbeats keep arriving, so the underlying read timeout sees bytes and never expires. The report includes a real langgraph dev check, but it remains an open issue rather than a documented product guarantee.
Name the two clocks
A transport read timeout limits the gap between received bytes. An application progress deadline limits the time without a meaningful event, state transition, or completed result. Those are different clocks. LangGraph's Streaming API guide describes streaming runs and client event handling; the issue shows why transport liveness alone cannot answer whether the agent is making progress.
Measure the stuck case
Record when the request starts, when the first response arrives, when the last decoded event arrives, and when the run reaches a terminal state. Test a slow but healthy node and a deliberately stalled node. Include the SSE heartbeats in diagnostics while excluding them from the progress metric. If a proxy or client UI disconnects, determine whether the server run continues and how the caller will reconcile its final state.
Put a bound where it can act
Define an end-to-end deadline for the customer journey and an idle-progress threshold for the stream. In async clients, a caller-side deadline can bound waiting; in sync clients, verify that cancellation or a server-side run limit actually interrupts blocked work before promising the same behavior. Give the user a recoverable state such as “still running” and a way to check status, rather than a spinner that cannot end.
Adovo’s view
Heartbeat is evidence of a pipe, not of a decision. Reliability means knowing when work has advanced and when it has stopped. Measure progress at the business boundary, then choose the timeout layer that can enforce it.
