Streaming Responses
First token fast, rest as they happen
Streaming sends tokens to the client as they are generated over SSE instead of after the full completion. It cuts perceived latency to the first token, keeps long generations from timing out, and is table stakes for chat UIs.
What you will learn
- Explain TTFT vs total latency
- Implement SSE streaming end to end
- Handle partial token buffers correctly
What is this?
Streaming serves text incrementally: the caller opens a connection (usually SSE), receives a chunk per token (or per delta), and renders it live. Non-streamed calls return a single body once the whole completion is ready.
Why do you need it?
- Users perceive a 300ms TTFT + flowing text as far faster than a 5s blank spinner.
- Long generations (agents, article drafts) otherwise risk client timeouts.
- You can cancel early (the famous stop mid-generation), saving tokens.
Mental model
Streaming
A voice call
You hear sentences arrive live; the alternative is a transcript that appears only when the call ends.
How it works
- The client opens an SSE (or chunked HTTP) connection and reads events.
- Server emits one event per delta; chat SDKs accumulate deltas into the visible message.
- When generation ends, send a [DONE] marker so clients close cleanly.
- Streams can also carry tool-call fragments, usage snapshots and signal names.
SSE lifecycle.
Examples
A minimal SSE handler shape
curl -N -X POST https://api.provider.dev/v1/chat/completions \ -H 'Content-Type: application/json' -d '{ "model": "fast-model", "messages": [{"role":"user","content":"write 3 haiku"}], "stream": true }' data: {"delta":"the "}data: {"delta":"moon "}data: {"delta":"over "}data: [DONE]Each data: line is one delta; most SDKs auto-accumulate. [DONE] is the well-known termination marker.
In production
- A chat UI renders streaming responses with a blinking cursor.
- An agent terminal shows tool calls arrive live and lets the user abort.
- A search page streams the answer above the links while links load underneath.
Best practices
- Set stream:true and expose TTFT (first chunk time) as a metric.
- Encode deltas UTF-8-safe; tokens may split multi-byte characters.
- Add client- and server-side timeouts aligned to generation length.
- Send heartbeat/keep-alive so idle streams aren't killed by proxies.
Common mistakes
- Buffering the whole stream server-side before forwarding — you lose the point.
- Not handling reconnection: a dropped stream corrupts the UI mid-render.
- Using the raw model stream but failing to strip control/thinking tokens for end users.
Debugging tips
- TTFT slow but streaming smooth = server queueing, not transport.
- Chunks arriving in bursts = buffering layers (proxy, framework) — check flush/stream settings.
- Partial multi-byte characters: join deltas before slicing, never per-chunk.
Interview checkpoint
Hands-on lab
- Feed a fake SSE response through a parser
- Accumulate deltas into a complete message
- Handle the [DONE] terminator
Parse an SSE Token Stream
25 min · intermediate
Quick quiz
What does TTFT stand for?
Streaming increases total token generation time.