The token cost of long agent runs compounds harder than I expected — I measured 66 real sessions

Full disclosure up front: I run an autonomous AI dev studio, and one thing that kept surprising us was how quickly long agent runs get expensive. So I instrumented 66 real coding-agent sessions and broke the spend down by turn, role, and session. Sharing the numbers because the mechanism applies to any agent loop — LangChain AgentExecutor, LangGraph, tool-calling chains, anything that re-sends state each step.

The core issue: every step, the model is billed for the entire context it receives — system prompt + accumulated message history + every prior tool result + the new input. Not just the new tokens. In an agent loop that keeps appending tool outputs, the per-step input grows monotonically, so cost per step climbs even though the “question” isn’t getting harder.

What I measured across the 66 sessions:

Metric Value
Total input tokens ~89M
Total output tokens ~47M
Input:output ratio ~1.9:1
Median session length 23 turns
Longest session 1,270 turns
Cost of the single longest session ~$1,278 (more than all other sessions combined)

Input dwarfs output ~1.9:1 — you pay far more to feed the loop than to get answers out of it. And the cost curve per step is roughly linear in accumulated context:

Step Approx context Cost/step (at $3/M input)
1 ~2K tokens ~$0.006
10 ~12K tokens ~$0.036
50 ~55K tokens ~$0.165
100 ~110K tokens ~$0.33
200 ~200K tokens ~$0.60

By step 200 each step costs ~100x step 1 — same model, same task, just carrying more history.

The three multipliers that hurt most in practice:

  1. Tool results are the biggest line item. In tool-heavy agents, raw tool output (search dumps, file reads, API JSON) was often the single largest share of input. Trimming/summarizing tool results before they re-enter context was the highest-ROI lever we found.
  2. History never self-prunes unless you make it. A naive loop re-sends turn 1 at turn 200.
  3. The tail is brutal. A tiny fraction of runaway-long sessions dominated total spend.

Genuine questions for people running long chains/agents here:

  • How are you bounding context in long AgentExecutor / LangGraph runs — windowing, running summaries, trim_messages, hard step caps, or something smarter?
  • Do you summarize or truncate tool outputs before they go back into the prompt, and how do you avoid dropping something the agent later needs?
  • Has anyone found a clean way to detect a runaway loop early rather than eating the whole bill?

Happy to share more of the breakdown methodology if it’s useful. Curious whether others see the same ~1.9:1 input:output and the same “tool results dominate” pattern.

Really solid instrumentation! thank you for publishing the actual numbers. The 1.9:1 input:output ratio and the way cost per step scales with accumulated context matches what we’ve been seeing in longer coding and research agents.

One lever that has been surprisingly high-ROI for us on the “tool results dominate” part:

A lot of the growing context in our runs was retrieved documents, search dumps, API responses, and docs that were already aging or superseded. Instead of only summarizing or windowing the entire history, we started hard-gating those chunks on temporal decay before they re-enter the agent context.

We put a thin OpenAI-compatible proxy (KU-Gateway) in front of the model. It extracts the context blocks / tool results, scores each one with a platform-aware half-life (GitHub ~180 days, arXiv longer, etc.), and drops anything above a decay threshold. Only the fresher material gets forwarded. Fail-open by design so it doesn’t break the loop if scoring fails.

On tool-heavy sessions this consistently removed a meaningful slice of the input tokens that would otherwise keep getting re-sent every subsequent turn. It doesn’t solve the pure conversation-history growth problem (you still want trim_messages / running summaries / step caps for that), but it attacks the part of the tool-result bloat that is both expensive and actively harmful (stale or contradicted information).

Curious how others are handling the quality/freshness of the tool outputs themselves, not just their length. Happy to share the exact threshold settings or a minimal LangChain example if useful.