Streaming AI Replies in Go with SSE
§1 Token streams make Go chat services feel responsive
A traditional AI request makes the user wait until the entire answer is ready. A streaming request delivers small pieces as the model generates them, so your application can display a reply while it is still being written. This improves perceived responsiveness without necessarily reducing the total generation time.
For a Go service, the basic path is straightforward: receive a user message, request a streaming response from an AI API, and forward each piece to the client. Keep the upstream API credential on your server, not in browser code.
§2 SSE carries live replies over HTTP
Server-sent events, or SSE, is a text format for sending a sequence of events through one HTTP response. It suits AI replies because the answer mostly travels in one direction, from your service to the browser. You do not need WebSockets just to display generated text.
An SSE response uses the content type text/event-stream. Each event consists of fields such as data, followed by a blank line. An event can carry a text fragment, a status update, or an error. A streamed fragment is not guaranteed to equal one token or one word.
The browser's built-in EventSource interface normally opens a GET request. For chat endpoints that accept a POST body, use fetch and read its response stream, or separate message submission from the event connection.
§3 A Go handler connects two streaming HTTP requests
Your handler manages two connections: the incoming browser request and the outgoing AI request. With an OpenAI-compatible chat endpoint, the upstream request typically enables streaming with stream set to true. Use an SDK that exposes streaming events, or parse the upstream SSE format carefully.
- – Validate the user's message and enforce request limits before opening the stream.
- – Create the upstream request with the incoming request's context so cancellation can propagate.
- – Check the upstream status before committing a successful streaming response to the browser.
- – Set streaming headers, write each complete downstream event, and flush it promptly.
- – Close the upstream response body when the handler finishes.
Go's http.ResponseWriter can buffer output. On supported writers, http.NewResponseController(w).Flush() pushes buffered data onward. Check flush errors and stop forwarding when the client connection fails. Flushing your application does not guarantee that an intermediary will immediately deliver those bytes.
§4 SSE parsing needs more than reading arbitrary chunks
Network reads do not preserve event boundaries. One read might contain half an event or several events together. Accumulate data until a complete SSE event is available, then decode its payload. Follow the upstream API's rules for completion markers and non-text events.
If you use bufio.Scanner, configure an appropriate maximum token size rather than relying on its default limit. Also check Scanner.Err() after scanning. Otherwise, a larger event or a broken connection can look like an ordinary end of response.
§5 Disconnects and proxy buffering affect real-time delivery
A browser tab can close halfway through an answer. Propagate cancellation upstream to avoid continuing unnecessary generation, although cancellation cannot undo tokens already generated or guarantee immediate billing termination.
Review reverse-proxy buffering, compression, and timeout settings. A correctly flushed Go handler can still appear non-streaming if a proxy collects its output. Test through your deployed infrastructure, not only on localhost. Use suitable connection and idle limits rather than a short total timeout that cuts off valid replies.
Once response headers have been sent, you cannot replace the stream with a new HTTP error status. Define a downstream error event and a completion event so the interface can distinguish success, failure, and an interrupted connection.
§6 Fluxio fits an OpenAI-compatible streaming backend
Fluxio is a streaming-first, pay-per-token AI API relay that lets a Go backend access multiple model providers with one key. Its API base is https://api.fluxioapi.com; OpenAI-style clients use https://api.fluxioapi.com/v1. That makes it a practical option when you want one integration for token-by-token replies.
Keep its key in server-side configuration, verify the available model identifiers, and measure time to first content alongside total response time. Your client should show a waiting state before content arrives and preserve partial text if generation stops unexpectedly.
Sign up for Fluxio to try streaming AI replies.