A dropped stream fails in two directions, and they look different to the user. In one case the client renders the same token twice: the server wrote chunk 151, the connection died before the write was confirmed, and the reconnect replays it. In the other case the client is simply missing chunks 151 and 152 and keeps rendering from 153 onward, which produces a response with a hole in the middle and no error anywhere. Ably's write-up on resume tokens makes the point that duplicates happen when the connection drops after delivery but before acknowledgment, while gaps happen when later messages arrive without the earlier ones.
The companion client-side article covers how the client machine stores the last processed position. This one is about the server contract: what the API has to carry so a reconnecting client can rejoin mid-object and receive exactly the missing tail.
There is a reason this matters more for token streams than for ordinary event feeds. A partial LLM response is not a sequence of independent events; it is a document being assembled. If your UI parses the stream incrementally, a duplicated token corrupts a string or a number, and a gap corrupts structure. The analysis of streaming JSON parsers describes why JSON.parse is all-or-nothing and why teams end up writing a stateful partial parser: once you have one, the parser's state is exactly the thing you must be able to rehydrate after a drop. Sequence numbers are how you tell the parser where it stopped.



