Every time your Claude agent takes a turn, it re-uploads the entire conversation — all prior messages, all assistant responses, the system prompt, every tool definition. At ten turns in a coding session that might be 100KB. At fifty turns with tool calls and screenshots, it is megabytes of JSON sent on every single request. Anthropic just fixed that. As of November 2, 2026, Message Threads are in public beta on the Messages API: agents now send only the new message per turn, and the API caches the rest server-side.
What actually changes (and what doesn’t) #
The headline metric is a 35% median drop in time to first token for conversations in the 500K–1M token range. That is a real number for real workloads — long coding agent loops, computer-use sessions dragging repeated screenshots through the context, document-heavy Q&A with dozens of follow-ups.
What does not change: cost. Claude still reads the full conversation on every turn. Token billing is identical. This is a network and serialization optimization, not a pricing break. If you are running agents expecting an invoice reduction, you will be disappointed. If you are running agents frustrated by latency creeping up turn by turn, this is exactly what you have been waiting for.
Add it with the SDK helper (two-minute migration) #
The SDK helper is the right path for most developers. It manages thread IDs, adds the required beta header, and automatically replays the full conversation if the thread expires. Here is the Python version:
client = anthropic.Anthropic()
thread = client.beta.messages.thread(
model="claude-opus-5-5",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system="You are a coding assistant. Be direct and concise.",
)
thread.send({"role": "user", "content": "Review this function for bugs."})
response = thread.send(
{"role": "user", "content": "Now suggest how to add error handling."}
)
TypeScript is the same shape:
const thread = client.beta.messages.thread({
model: "claude-opus-5-5",
max_tokens: 1024,
cache_control: { type: "ephemeral" },
system: "You are a coding assistant. Be direct and concise."
});
await thread.send({ role: "user", content: "Review this function for bugs." });
const response = await thread.send({
role: "user", content: "Now suggest how to add error handling."
});
The helper is available in Python, TypeScript, C#, Go, Java, PHP, and Ruby. If you are already using the SDK, the migration is replacing client.messages.create calls inside your agent loop with the thread helper. The SDK adds the message-threads-2026-08-12 beta header automatically on every request.
The manual path (for cURL and non-SDK setups) #
If you are calling the API directly, three things change. Add the beta header to every request in the thread:
anthropic-beta: message-threads-2026-08-12
On the initial request, add "thread": {"type": "create"} to the JSON body. On every subsequent request, omit system and tools entirely, and add:
"thread": {"type": "continue", "previous_message_id": "<id from previous response>"}
If a continue request returns a 404 with thread_not_found, the thread expired. Resend the full conversation as a new create request and continue from there. Keep your own copy of the conversation — the thread is a server-side cache, not persistent storage.
Caveats worth reading before you deploy #
Threads expire five minutes after the last request, not five minutes from creation. Each stored response resets that clock. For typical interactive agents with sub-minute turn cycles this is fine. For workflows with long s between turns, plan for replays.
Message threads are not eligible for Zero Data Retention. The conversation is held encrypted in memory and never written to disk, but it does not qualify as ZDR. If your organization has ZDR, HIPAA readiness, or Inference hooks enabled, threads are not currently available.
Several features do not work inside a thread: Message Batches, token counting, compaction on demand, and most context editing. If your pipeline relies on any of these, stay on the standard create flow for now.
One more rule: a handful of fields are “fixed” for the life of a thread — model, tool_choice, thinking, and the top-level cache_control. Send the same values on every request. A different value returns a thread_fingerprint_mismatch error.
Stack it with prompt caching for the full combination #
Message threads and prompt caching solve different parts of the latency problem. Threads cut upload overhead — you stop resending the full conversation JSON each turn. Prompt caching cuts tokenization and processing overhead — Claude reads from cache instead of reprocessing your system prompt and tools from scratch. Together they deliver the most consistent TTFT across a long agent session.
The setup is passing cache_control: {"type": "ephemeral"} when creating the thread helper, as shown in the examples above. Because top-level cache_control is a fixed field, it applies automatically to every turn in the thread. One configuration line, two latency wins.
Who should enable this today #
If you are building coding agents, computer-use workflows, or any multi-turn agent loop that stretches past ten turns and already shows latency creep, enable threads now. The migration is small, the SDK handles replay edge cases, and the TTFT improvement is real.
If you are running batch jobs, relying on token counting for context management, or operating in a HIPAA or Inference hooks environment, hold off. The unsupported feature list is real, and hitting a thread_unsupported_request error mid-loop will cost more time than the latency savings are worth.
The official documentation covers every error code, fallback model handling, streaming edge cases, and the fork and compaction patterns. This is a beta — read the limitations section before shipping to production.