Member-only story
Streaming LLM Responses in Go: Server-Sent Events vs. WebSockets
A few months back I shipped a chat feature where the model’s answer just… appeared. All at once. Users would hit send, stare at a spinner for four to six seconds, and then get hit with a wall of text. Nobody complained in words, but the usage numbers told the story — people were abandoning mid-wait more than I expected for something that “worked.”
The fix wasn’t a smarter model. It was streaming. Once tokens started showing up within 300–400ms instead of after the full generation finished, the same backend felt like a completely different product. That gap between “technically correct” and “feels fast” is basically the whole reason this post exists.
If you’re building this in Go, you’ll land on the same fork in the road I did: Server-Sent Events or WebSockets. Both get tokens to the browser as they’re generated. They are not interchangeable, and picking the wrong one costs you either unnecessary complexity or a UX ceiling you’ll hit later.
Why streaming changes the UX math
Time-to-first-token (TTFT) is the metric that actually matters for perceived speed, not total generation time. A response that takes 5 seconds total but starts streaming at 300ms feels faster than one that takes 3 seconds and arrives as a single blob — even though the…









