I’m adding a chat-style AI assistant to an existing Blazor Server application, and streaming the response is where things fall apart.
My first attempt was the obvious one: take each piece of text as the model sends it, append it to the message, and refresh the UI every time. Locally with a single user it looks perfect. With a few concurrent sessions the circuit starts struggling, and on a slower connection the text appears in uneven bursts rather than flowing smoothly.
Thinking about it afterwards, that makes sense. Every UI refresh pushes an update over SignalR, and a long response means hundreds of those within a few seconds.
What I’ve tried since:
Buffering the text and refreshing on a timer instead of on every chunk. Rendering every 100 milliseconds improved things considerably. But I picked that number by trial and error rather than for any good reason, and I have no idea whether it is appropriate or whether it should adapt to connection conditions.
I also considered handling the streaming entirely on the browser side and only sending the finished response back to the server. That avoids the circuit problem completely, but it splits the logic across two places and I am not convinced the trade is worth it.
What I am trying to work out:
1. Is timer-based buffering the accepted approach here? If so, is there a sensible way to choose the interval, or is trial and error genuinely how everyone does it?
2. Has anyone handled the streaming display purely in the browser and only synced the final result to the server? Did you regret the added complexity?
3. How do you handle a user navigating away mid-response? I am passing cancellation through, but I am not confident the outbound call to the provider actually stops rather than just continuing in the background while nobody is listening. That has cost implications as well as resource ones.
4. Does Blazor WebAssembly change this enough to be worth considering, or does the larger initial download and authentication complexity outweigh the streaming benefit?
Running .NET 9 with a standard Blazor Server setup and no special SignalR configuration.
More interested in what is holding up in production than what works cleanly in a demo.

Replies
Know the answer? Post it — somebody with the same question will find it here.