Jorge Turbica / blog · Blog ← All articles ES · Leer en español
AI

Claude no longer needs the full history every turn: 35% faster first token

Message Threads, in beta on the Claude API, sends only what is new each turn. Same price, earlier first token, and new edge cases for your agent.

On requests of 500,000 to one million tokens, median time to first token drops by about 35%. That is the figure Anthropic gives for Message Threads, a Messages API feature in public beta since November 2, 2026: the client sends the full conversation once and, after that, only what is new on each turn. Per-token pricing stays the same, because Claude still reads the whole history; what goes away is uploading, validating and tokenizing the entire conversation again on every request.

What changes

Until now the Messages API has been stateless: every agent turn resends the system prompt, the tools and every earlier message and tool result. For a coding agent that makes hundreds of calls per session, that means hundreds of thousands of tokens travelling back and forth before the model starts answering.

With a thread, the first request carries the full conversation plus "thread": {"type": "create"}. Later requests carry only the new messages and "thread": {"type": "continue", "previous_message_id": "<id>"}, the id of the previous response. The server rebuilds the conversation before calling the model. Anthropic says the thread is held encrypted in memory, never written to disk, and expires 5 minutes after the last request (it is deleted at most an hour later).

It is available on the Claude API, Claude Platform on AWS, Microsoft Foundry and Claude Models on Google Cloud (Anthropic managed), for every model, behind the message-threads-2026-08-12 beta header. Pricing and rate limits are unchanged. According to the announcement, it is already on by default for most Claude Code users, which is where the 35% comes from.

Turning it on

The SDK ships a helper that creates the thread on the first turn, adds the beta header, leaves system and tools out of later turns, and replays the whole conversation when the thread is gone:

python
import anthropic

client = anthropic.Anthropic()

# The helper sends nothing until the first turn
thread = client.beta.messages.thread(
    model="claude-opus-5-5",
    max_tokens=1024,
    cache_control={"type": "ephemeral"},
    system="You are a support agent for Acme. Keep replies short.",
)

thread.send({"role": "user", "content": "Hi! I have a question about an order."})
second = thread.send({"role": "user", "content": "How long does standard shipping take?"})

The top-level cache_control is optional, but a thread does not cache anything on its own: without cache breakpoints, each turn sends less data, yet nothing is reused from the prompt cache. If you build the requests yourself, the beta header has to go on every one of them.

Versus OpenAI's previous_response_id

OpenAI solved the same problem a while ago in its Responses API, with a different take on storage:

Message Threads (Anthropic)previous_response_id (OpenAI)
Where state livesIn memory, encrypted, never on diskResponse objects stored for 30 days by default (store: false turns it off)
Expiry5 min idle; deleted within 1 h30 days
BranchingNo: append-only, each id can be continued onceYes, from any response still available
Tokens billedThe whole conversation, as beforeAll previous input tokens in the chain
ZDRNot eligible—

Anthropic's design is deliberately ephemeral: it exists to take latency out of an active agent loop, not to store your conversation. That is why the docs insist that your application stays the source of truth: keep your own copy of every message and build the full-replay path from day one.

Gotchas and edge cases

  • system and tools only on create. Sending either on a continue request, even as null, returns a 400. model, thinking, tool_choice, output_config and the top-level cache_control must be identical on every turn, or you get thread_fingerprint_mismatch. To change any of them, start a new thread.
  • The 404 is part of the flow. thread_not_found comes back when the thread expired, when a fallback model wrote the previous response, when you switch key or workspace, or when the API did not store the turn (for example, a tool call cut off by max_tokens). The response does not say which: replay the full conversation in a create request.
  • Not supported: Message Batches, token counting, on-demand compaction, most context editing, and organizations with HIPAA readiness or Inference hooks turned on. At most 4 cache_control breakpoints per request, and there is no API to list, read or delete threads.
  • Streaming: the id arrives in message_start, but you can only continue after message_stop. After a stop_reason: "refusal", do not continue: open a new thread without that turn.

The limit that weighs most is compliance: if your organization runs on zero data retention, this feature is off the table, because the conversation sits in the provider's memory for up to an hour. For everyone else running long-context agents, it is a few lines with the SDK helper, as long as the replay path is tested before you need it.

Sources

Jorge Turbica

Software Engineer and SRE. I write about the real challenges I run into in production.

See portfolio ↗