1. HTTP Chunked Transfer Encoding
1.1.Mechanism
Mechanism
Not SSE, not WebSocket. Plain HTTP/1.1 feature (RFC 7230).
When the server omits Content-Length and sets Transfer-Encoding: chunked, it can send the response body in pieces:
The client processes each chunk as it arrives without waiting for the full body.
1.2.Response Format: NDJSON (Newline-Delimited JSON)
Response Format: NDJSON (Newline-Delimited JSON)
Each chunk is one JSON object followed by \n. Simple to produce, simple to parse.
Alternatively, SSE (text/event-stream) uses the same chunked mechanism but with a specific format (data: ...\n\n) and built-in reconnection logic. Plain NDJSON streaming is simpler when we don't need to reconnect.
2. HTTP/1.1 Streaming from Backend
2.1.Python / FastAPI
Python / FastAPI
StreamingResponse sets Transfer-Encoding: chunked automatically. Each yield flushes one chunk immediately.
2.2.Node.js / Express
Node.js / Express
res.write() sends a chunk immediately. res.end() closes the stream. Express uses chunked transfer automatically when res.write() is called before res.end().
3. Receive HTTP/1.1 (NDJSON) Stream from Frontend
3.1.Client: fetch (Browser / Node.js)
Client: fetch (Browser / Node.js)
fetch exposes the response body as a ReadableStream. Read chunks with .getReader().
Remark (Why buffer splitting matters). A single read() call may contain multiple JSON lines, or a line may be split across two read() calls. Always accumulate into a buffer and split on \n.
3.2.Client: axios (Browser only)
Client: axios (Browser only)
axios has limited streaming support via onDownloadProgress, note that it gives the cumulative text so far, not just the new chunk.
In comparison, the native fetch for streaming gives true chunk-by-chunk control.
4. Lambda Streaming (AWS)
Standard Lambda + API Gateway always buffers to produce a full response, chunked encoding is stripped at the gateway.
To stream from Lambda we must:
- Use Lambda Function URL (not API Gateway) with
InvokeMode: RESPONSE_STREAMinstead of using API gateway - Python may need to remove Mangum (it's a buffered adapter) or use Mangum v0.17+ streaming mode.
- Make sure to remove all authentication type
- Create inline policies to allow public access
The function URL looks like: https://<id>.lambda-url.<region>.on.aws/
5. Comparison: SSE vs WebSocket vs Chunked HTTP
| Chunked HTTP | SSE | WebSocket | |
|---|---|---|---|
| Direction | Server → Client only | Server → Client only | Bidirectional |
| Protocol | Plain HTTP | HTTP (text/event-stream) | Protocol upgrade |
| Reconnect | None | Built-in | Manual |
| Format | Any | data: ...\n\n | Any |
| Complexity | Lowest | Low | Higher |
| Use case | One-shot stream (RAG answer) | Live feeds, notifications | Chat, real-time collab |




