• On a claude.ai login against Anthropic's own API, Claude Code 2.1.319 sends the full conversation once, then only the new messages on every request after that. It's on by default and the changelog doesn't mention it.
  • It does nothing for your bill. Cached input tokens were the same with threads on and off. At about 74,000 tokens of context I measured no speed gain either.
  • It's switched off on Bedrock, Vertex, Foundry, behind any proxy or gateway, and for zero-data-retention and HIPAA orgs. An undocumented CLAUDE_CODE_TETHER_LIVE variable switches it on or off.

Anthropic opened message threads on the Messages API as a public beta on 2 November. The idea is simple. An agent loop normally resends the entire conversation on every turn: system prompt, tool definitions, every earlier message. With a thread, the first request is a create, and each later one is a continue that carries only the new messages plus the ID of the previous response. The server holds the rest for five minutes.

Coverage of the launch said Claude Code already uses it. Nothing in the Claude Code changelog says so, so I put a logging proxy in front of api.anthropic.com and watched what 2.1.319 actually sends.

What goes over the wire

The test was deliberately small: a throwaway folder with two one-word files, and Haiku 5.5 told to read them in two separate tool calls and then answer. That's three model requests in one turn. I ran it four times with threads on and four times with them off.

With threads off, the three requests were 185,063, 192,755 and 197,925 bytes. Each one carries 10 KB of system prompt, 66 KB of tool definitions and the whole message history, growing as the tool results pile up. That's about 575 KB to ask about two words.

With threads on, the first request was 189,090 bytes with "thread": {"type": "create"}. The next two were 839 and 838 bytes, each with "type": "continue" and a previous_message_id pointing at the response before it. No tools field at all. The only system content left is a 111-byte block holding Claude Code's billing tag. Across the four runs the follow-up requests ranged from 838 bytes to 12 KB, the bigger ones carrying a tool result or a mid-conversation system note.

Before trusting the proxy I checked the default path, with no proxy and no overrides. The SDK's debug log showed thread in the request body and message-threads-2026-08-12 in the beta header on the main-loop requests. On this account the server-side flag that controls it, tengu_curious_tower, is cached as true.

What it doesn't change

A thread doesn't cache your prompt and doesn't change pricing, and Anthropic's docs say both outright. The usage numbers bear it out. The continue requests reported 72,354 to 73,863 cached input tokens read. The stateless follow-ups read 70,494 to 73,857. The model still reads the whole conversation every turn, and you still pay for it.

Speed is the selling point, and I couldn't see it at this size. Across eight continue requests the median time to first byte was 1.12 seconds. Across eight stateless follow-ups it was 0.96 seconds. That's a small sample through a local proxy, so I'd call it a wash rather than a loss. The 35 percent faster first token in the launch coverage was measured on requests of 500,000 to a million tokens, and Anthropic's own page gives no figure, only that time to first token "stays lower and steadier" as the conversation grows. Uploading 190 KB is trivial. Re-reading a million-token body on every turn isn't.

If your Claude Code sessions sit at 50,000 to 100,000 tokens, threads are plumbing you won't notice. If you run long sessions near the top of a 1M context window, that's where it should pay off.

Who doesn't get it

The gate is in the binary, and it's narrow. Threads are only used when the provider is Anthropic's first-party API. Set CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX, CLAUDE_CODE_USE_FOUNDRY or point Claude Code at a gateway and it's off. That's true even though the API itself offers threads on Claude Platform on AWS, Google Cloud and Microsoft Foundry. Orgs flagged zero-data-retention or HIPAA are excluded, matching the API's own eligibility table, which marks threads "not-eligible" for ZDR.

An ANTHROPIC_BASE_URL that doesn't point at Anthropic also turns it off. That covers LiteLLM, a corporate egress proxy, or a logging proxy like the one I used. That part is good news if you audit Claude Code traffic at a proxy: your logs still hold whole conversations, not 838-byte fragments.

There are two switches. CLAUDE_CODE_TETHER_LIVE=0 turns threads off, and =1 forces them on even behind a proxy, which is how I captured the bodies above. I couldn't find it in the changelog or the environment variable docs. CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 also turns threads off, but it's a blunt tool. On my machine, with a long list of MCP servers configured, it also dropped the beta that defers tool definitions. The first request came to roughly 1.11 million tokens against a 1 million limit and failed with "Prompt is too long." With --strict-mcp-config the same switch worked fine.

How Claude Code handles the five-minute clock

The server forgets a thread five minutes after its last request. A continue on an expired thread gets a 404 thread_not_found, and the docs say the response "does not say why." Claude Code doesn't wait to find out. It tracks idle time on its side against a 300-second lifetime (a server-tunable value between 300 and 3,600 seconds) and sends a fresh create once that passes.

I checked this with a session kept open over stream-json: two quick turns, then 315 seconds of silence, then a third message. The third turn went out as a create with all 11 messages, 194,828 bytes, and succeeded on the first try. No 404, no retry.

Resuming a session in a new process works the same way. claude -p --resume sent a create with the full nine-message history, because thread state lives in the running process and nowhere else. Side requests such as Claude Code's own classifier and summary calls, about 21 KB each, never use a thread.

The binary also shows how it fails safe. A 404 replays the full conversation. A fingerprint mismatch, where the model, thinking settings or beta headers no longer match the thread, gets the full fields resent. An HTTP 400 it doesn't recognise on a threaded request is retried without the header, and threads stay off for the rest of the session.

If you're building your own agent loop

Claude Code is a good reference implementation, and the docs line up with it. Keep your own full transcript, because there's no API to read a thread back. Send system and tools only on the create. Continue from the latest response ID only, since each ID can be continued once. Track the five minutes yourself and fall back to a full create on a 404, thread_already_continued or thread_continue_in_flight. The official SDKs now ship a client.beta.messages.thread() helper that does that replay for you.

Check your tracing before you switch. If your observability layer records request bodies, a threaded agent's spans will hold the new messages and an ID, not the conversation. At least one tracing SDK already has an issue filed about not capturing the thread parameter at all.

And measure at your real context size. My numbers say threads are free to turn on and don't change the bill. Whether they speed anything up depends on how much context you're dragging around. Below about 75,000 tokens, I couldn't tell the difference.