中文
← Back to tutorials

Streaming AI Responses with Server-Sent Events: Complete Developer Guide 2026

Master Streaming AI Responses with Server-Sent Events with practical examples and production patterns

By AI Skill Navigation Editorial TeamPublished June 9, 2026

Implementing AI Streaming Responses with Server-Sent Events (2026)

Streaming makes AI apps feel fast: instead of waiting for a complete answer, tokens appear as they are generated. Server-Sent Events (SSE) is the simplest transport for this—a unidirectional stream from server to browser over plain HTTP, perfect for LLM token streams. This guide shows the full path from model to browser.

Why SSE (Not WebSocket)

LLM streaming is unidirectional (server → client), so WebSocket's bidirectional complexity is unnecessary. SSE is just an HTTP response with Content-Type: text/event-stream, keeping the connection open and sending data: lines. The browser automatically reconnects via the EventSource API.

Server Side (FastAPI)

python

pip install fastapi openai sse-starlette uvicorn

from fastapi import FastAPI from sse_starlette.sse import EventSourceResponse from openai import OpenAI

app = FastAPI() client = OpenAI()

@app.get("/chat") async def chat(q: str): async def gen(): stream = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": q}], stream=True, ) for chunk in stream: delta = chunk.choices[0].delta.content if delta: yield {"data": delta} yield {"event": "done", "data": "[DONE]"} return EventSourceResponse(gen())

Client Side (Browser)

js
const es = new EventSource('/chat?q=' + encodeURIComponent(input));
es.onmessage = (e) => { output.textContent += e.data; };
es.addEventListener('done', () => es.close());

That's the whole loop: each token arrives as a message event and gets appended to the UI.

Production Considerations

  • Disable proxy buffering (e.g., Nginx's X-Accel-Buffering: no), otherwise data chunks are held back and the stream stalls.
  • Flush per token. Any buffering layer between the model and the client breaks streaming.
  • Handle disconnection. If the user navigates away, cancel the upstream model call to stop billing.
  • Next.js note: The Vercel AI SDK wraps all this—streamText + useChat lets you stream without hand-rolling SSE. See Vercel AI SDK vs LangChain.js.
  • Backpressure/fan-out: For many concurrent streams, serve with an engine designed for it—see LLM Inference Optimization.
  • FAQ

    SSE or WebSocket? SSE for unidirectional token streams—simpler and auto-reconnects. Only use WebSocket if you need bidirectional real-time communication. Why does my stream arrive all at once? A buffering proxy is in the way. Disable buffering and flush chunk by chunk. How to stop billing on disconnect? Detect client disconnect and cancel the upstream completion.

    Summary

    SSE is the path of least resistance for LLM streaming: open a text/event-stream, yield tokens as they arrive, and append them in the browser with EventSource. Disable buffering, flush per token, and cancel on disconnect. On Next.js, let the Vercel AI SDK handle it.


    *Last updated: June 2026. Verify streaming APIs against OpenAI and framework docs.*

    Also available in 中文.