If you call Claude on Bedrock's classic runtime surface with InvokeModel, the streaming upgrade costs almost nothing: InvokeModelWithResponseStream takes the identical request — the Anthropic Messages body with "anthropic_version": "bedrock-2023-05-31", max_tokens, and messages — and returns the response incrementally instead of all at once. For chat interfaces and anything a human watches, that transforms perceived latency: the first words appear as soon as the model produces them.
What's actually on the wire
A clarification worth making early, because it trips up teams writing their own HTTP clients: this operation's stream is often described loosely as "SSE," but on the legacy bedrock-runtime surface the wire format is AWS's binary event-stream encoding, not the plain-text Server-Sent Events format. Anthropic's docs draw exactly this distinction — the newer "Claude in Amazon Bedrock" surface (bedrock-mantle) streams standard SSE, while the legacy surface uses AWS event-stream encoding. In practice this rarely matters, because the AWS SDKs decode the event stream for you: each decoded chunk carries a JSON payload, and those payloads are the familiar Anthropic Messages streaming events — a message start, a sequence of content deltas, and a message stop with final metadata.
Consuming the stream in Python
With boto3, the response body is an iterator of events; each event's chunk contains bytes you parse as JSON. A minimal consumer that prints text as it arrives:
import boto3, json
client = boto3.client("bedrock-runtime", region_name="us-east-1")
resp = client.invoke_model_with_response_stream(
modelId="global.anthropic.claude-opus-4-6-v1",
body=json.dumps({
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 512,
"messages": [{"role": "user", "content": "Write a haiku about queues."}],
}),
)
for event in resp["body"]:
chunk = json.loads(event["chunk"]["bytes"])
if chunk.get("type") == "content_block_delta":
print(chunk["delta"].get("text", ""), end="", flush=True)
Real applications handle the other event types too: start events tell you a content block is opening (useful for rendering code blocks or tool calls distinctly), and the closing events carry the stop reason and usage information you'll want for logging and cost tracking. Accumulate the deltas into a complete message before storing it in conversation history.
Timeouts and stream hygiene
Two timeout layers matter. Bedrock's inference timeout for Claude 4-generation models is 60 minutes — but AWS SDK clients default to roughly a 1-minute read timeout, and AWS recommends raising it (botocore read_timeout of 3600 or more) so a long generation, or a long pause during extended thinking, doesn't sever the stream. Also decide what a mid-stream failure means for your product: some content has already arrived, so choose between discarding the partial answer, marking it as truncated, or retrying and replacing it. If the user abandons the page, cancel the request — every additional token is billed whether or not anyone reads it.
Permissions and observability
The caller needs bedrock:InvokeModelWithResponseStream on the relevant foundation-model ARN — and on the inference-profile ARN as well if you route through a cross-region inference profile such as the global.-prefixed model IDs. Streaming invocations are logged as CloudTrail management events by default, and model invocation logging (when enabled) captures request and response data for streaming calls on the bedrock-runtime endpoint. Tokens streamed count against the same per-model tokens-per-minute quotas as non-streaming calls, with input and output counted together on this endpoint.
One eye on the model lineup
This operation lives on the legacy surface, whose ARN-versioned IDs stop before the newest generation: Claude Fable 5, Opus 4.8, and Opus 4.7 have no ARN-versioned IDs, and Sonnet 5 is not on the legacy surface at all. If you need those models, the current Claude in Amazon Bedrock surface streams the same Anthropic event types over standard SSE — so consumer code organized around Anthropic's streaming events ports over naturally.
Where to go next
Compare with the unified-API alternative in streaming via ConverseStream, review the request body rules in InvokeModel in depth, or plan for backpressure with the throttling guide.