API Features & Capabilities

Conversation History Sizing: Trimming the Messages Array Without Losing Coherence

Every turn you append to a conversation is re-sent, re-processed, and re-billed on the next request. Long-running assistants need a deliberate policy for what stays and what goes.

Claude 3P 101 · Updated July 2026 · Unofficial guide

The Messages API is stateless: the model sees exactly the messages array you send, every time. Everything in the request counts toward the context window — system prompt, all prior turns including tool results, images, and documents, tool definitions, and the output being generated. Even 1M-token models (Opus 4.8 and Sonnet 5 among them) eventually fill up in agentic workloads, and cost grows with history long before the hard limit does. When input alone exceeds the window, the API returns a 400 "prompt is too long" error; on Claude 4.5-and-later models, input plus max_tokens overflowing instead stops generation with stop_reason: "model_context_window_exceeded". Your history policy decides how gracefully you approach either edge.

Client-side strategies

Sliding window. Keep the system prompt plus the most recent N turns; drop the oldest. Simple and predictable, but old decisions vanish entirely — fine for casual chat, risky for workflows where turn 3 established constraints that still bind turn 40. Always drop whole turns and keep the array's structure valid: an assistant message with tool_use blocks and the user message carrying its tool_result blocks must be removed together, never split.

Selective summarization. Replace a span of old turns with one compact turn summarizing decisions, facts, and open items — a cheap model like Haiku 4.5 can write the summary. This preserves coherence at a fraction of the tokens, at the cost of an extra call and possible loss of detail.

Pinning critical context. Durable constraints (the user's goal, account facts, rules established mid-conversation) shouldn't live only in trimmable turns. Promote them into the system prompt or a pinned block near the top so trimming never deletes them. Anthropic's long-context guidance reinforces the shape: longform reference material belongs at the top, the live query at the end.

Rule of thumb: trim in large, infrequent steps rather than one turn at a time. Prompt caching is a strict prefix match — every trim rewrites the start of the prompt and invalidates cached prefixes from that point — so trimming every turn can cost more in cache re-writes than the tokens it saves.

Measure before you trim

The token counting endpoint (count_tokens) accepts the same inputs as message creation, is free, and has its own generous rate limits — use it to enforce a budget instead of guessing from character counts. Two cautions: counts are model-specific (Opus 4.7-and-later models, including Opus 4.8 and Sonnet 5, tokenize ~30% heavier than earlier generations), and thinking blocks from previous assistant turns do not count toward input tokens, so naive estimates can overshoot.

count = client.messages.count_tokens(model="claude-sonnet-5",
                                     system=system, messages=history)
while count.input_tokens > BUDGET:
    history = summarize_oldest_span(history)   # or drop whole turns
    count = client.messages.count_tokens(model="claude-sonnet-5",
                                         system=system, messages=history)

Server-side alternatives: context editing and compaction

Anthropic now offers two beta features that do this work on the server, leaving your local history untouched. Context editing (context_management.edits, beta header context-management-2025-06-27) automatically clears old tool results once input exceeds a trigger — by default 100,000 tokens, keeping the last 3 tool uses — which targets exactly the content that dominates agentic histories. Compaction (compact_20260112, beta header compact-2026-01-12) goes further: near a configurable trigger (default 150,000 tokens) the model summarizes older conversation into a compaction block; you append the response as usual and the API drops everything before that block on the next request. Responses report what was removed via context_management.applied_edits, and count_tokens returns both the post-edit count and original_input_tokens so you can quantify the savings. If you'd rather not hand-roll summarization, compaction is effectively the managed version of it.

One platform note: these are beta features — currently listed as beta across platforms — so verify availability on your platform before depending on them, and keep a client-side fallback.

Things that must survive any trim

Whatever policy you choose, three invariants hold. The latest assistant turn's thinking blocks must be passed back exactly as received — modifying or filtering them returns a 400. Tool-use/tool-result pairs stay together. And when switching models mid-conversation, strip thinking blocks from prior assistant turns, since other models ignore them while still paying input tokens for them.

Where to go next

The server-side features have dedicated guides in Context Editing and Context Compaction. The cache interaction is unpacked in Cache Read vs Write Tokens, and window fundamentals in Context Windows.

Sources