---
title: "Comment by Skillselion on \"The User Stopped Reading at Token Two: Streaming Chat on .NET\" | Hashnode"
description: "Dropped cancellation as the worst failure mode rings true, and your line about it, \"There is no error in the log to grep for, which is exactly why it survives t"
url: "https://hashnode.com/posts/streaming-chat-dotnet-iasyncenumerable-signalr/6a7d3350643087334240718b/comment/6a7db1b6f90f7dcc95876dcb"
---

[Discussion](https://hashnode.com/posts/streaming-chat-dotnet-iasyncenumerable-signalr/6a7d3350643087334240718b)

Comment [The User Stopped Reading at Token Two: Streaming Chat on .NET](https://hashnode.com/posts/streaming-chat-dotnet-iasyncenumerable-signalr/6a7d3350643087334240718b)

[Skillselion](https://hashnode.com/@skillselion)

[Aug 13](https://hashnode.com/posts/streaming-chat-dotnet-iasyncenumerable-signalr/6a7d3350643087334240718b/comment/6a7db1b6f90f7dcc95876dcb)

Dropped cancellation as the worst failure mode rings true, and your line about it, "There is no error in the log to grep for, which is exactly why it survives to the invoice.", suggests the missing runtime guard: make the silence measurable. Emit two counters per streaming request, tokens billed by the provider and tokens actually flushed to a live connection, and chart the delivered ratio. A healthy endpoint sits near 1.0; a dropped token at any of your five layers shows up as a sagging ratio within hours instead of surfacing on next month's invoice, and it localizes the leak because you can tag the ratio by transport and route. It slots naturally into the OpenTelemetry span you already have covering the enumeration. Your checklist verifies cancellation end to end at test time; this watches it in production, where the proxy config drifts after the test passed. Was a metric like that omitted for length, or do you see a flaw in it?

[Alen Joy](https://hashnode.com/@alenj)

[Aug 18](https://hashnode.com/posts/streaming-chat-dotnet-iasyncenumerable-signalr/6a7d3350643087334240718b/comment/6a7db1b6f90f7dcc95876dcb#reply-6a83e45396fc5fe66a13321a)

Honestly, a bit of both. Fair to leave out, but the way you've framed it has a hole worth naming. If you get the billed number by counting the updates you read off the stream, what you're really measuring is how many tokens you pulled, not how many the provider charged you for. Those two only come apart in the exact case you care about, when the provider keeps billing for a response the user already walked away from. That figure only lands in the final usage message at the end of the stream, and if you cancelled early you never see it, so your ratio sits at a happy 1.0 and the leak still turns up on the invoice.

Two smaller things. It's a ratio, so it hides the size of the problem. A reconnect storm can keep every stream near 1.0 while your spend runs ten times over. And a delivered count taken on the server can't tell a token the user actually saw from one the proxy is sitting on. None of that kills the idea though. I'd just ship it as a plain counter of pulled minus delivered with an alert on the tail, take the billed figure from the provider's own usage once the stream finishes, and trust it more on SignalR than SSE. Good catch.
