Streaming in LangChain: A Complete FastAPI + SSE Implementation

By Carlos Montiel | Enterprise AI Specialist
Leer en español →
Published: 2026-07-28 | By: Carlos Montiel | Reading time: ~4 minutes

The streaming example in most tutorials works in a terminal. Putting it into production behind a real endpoint requires a few more pieces.

The base pattern: astream() inside an async endpoint

Integrating LangChain with FastAPI means defining async endpoints that call `chain.ainvoke()` for complete responses or `chain.astream()` for token streaming. You can create an endpoint that streams events using Server-Sent Events (SSE) over a RAG pipeline — the typical pattern uses a FastAPI endpoint with `StreamingResponse`, iterating asynchronously through `chain.astream()` and emitting data in SSE format.

Reference code

from fastapi import FastAPI from fastapi.responses import StreamingResponse import json app = FastAPI() @app.get("/chat/stream") async def chat_stream(message: str): async def event_generator(): async for chunk in chain.astream({"text": message}): yield f"data: {json.dumps({'content': chunk})}\n\n" yield f"data: {json.dumps({'type': 'done'})}\n\n" return StreamingResponse(event_generator(), media_type="text/event-stream")

astream_events for fine control over what gets streamed

LangChain's `astream_log` method uses JSON Patch to stream events, giving an efficient way to incrementally update parts of a JSON document. Callbacks intercept lifecycle events across every LangChain component, allowing granular control over streaming behavior — with `astream_events` you can stream agents token by token and wire it up to FastAPI's SSE for an experience with no loading spinners.

The 4 pieces of a production-ready setup

A production-ready configuration needs: an async FastAPI endpoint calling `chain.ainvoke()` or `chain.astream()`; structured error handling that catches `openai.RateLimitError` and `LangChainException` separately (not a generic catch-all); CORS middleware with explicitly allowed origins; and a Gunicorn process manager running 4 or more Uvicorn workers.

The most common mistake: mixing sync and async

Use `chain.ainvoke()` for single responses and `chain.astream()` for token streaming — never call synchronous methods inside async handlers. This is the most common production bug in LangChain + FastAPI integrations: a blocking synchronous method inside an async handler blocks the entire event loop, degrading the latency of every other concurrent request, not just the one that called it.

Carlos Montiel
Enterprise AI Solutions Architect
Specialist in LLMs, Agents, and Orchestration
guatemalia.com/en/#contact · info@guatemalia.com

Need to implement AI at your company?

Carlos Montiel is an enterprise AI solutions architect. He implements LLMs, Agents, RAG, and orchestrators for companies across Guatemala and Latin America. Reach out for a consultation.

Contact Carlos Montiel

info@guatemalia.com