<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tomás Alcalde</title>
    <description>The latest articles on DEV Community by Tomás Alcalde (@talcaldeg).</description>
    <link>https://dev.to/talcaldeg</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4105068%2F7be5cbc7-6d51-4e92-bf68-7de0cd836edc.png</url>
      <title>DEV Community: Tomás Alcalde</title>
      <link>https://dev.to/talcaldeg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/talcaldeg"/>
    <language>en</language>
    <item>
      <title>The note was fine; finding it was the problem</title>
      <dc:creator>Tomás Alcalde</dc:creator>
      <pubDate>Tue, 13 Oct 2026 13:42:10 +0000</pubDate>
      <link>https://dev.to/talcaldeg/the-note-was-fine-finding-it-was-the-problem-5cph</link>
      <guid>https://dev.to/talcaldeg/the-note-was-fine-finding-it-was-the-problem-5cph</guid>
      <description>&lt;p&gt;I work with a coding agent that keeps what it learns in text notes: one per topic, with a&lt;br&gt;
current state at the top that gets rewritten and a dated history at the bottom that only grows.&lt;br&gt;
Today there are 220 notes and almost a million tokens. Nobody loads them whole. On every message a&lt;br&gt;
word-based search suggests which ones might help, the agent asks for a map of sections with the&lt;br&gt;
cost of each, and fetches only the one it needs. I have been calling that the ladder.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://talcaldeg.github.io/articulos/small-levers/" rel="noopener noreferrer"&gt;the previous article&lt;/a&gt; I put it next to Mem0, Zep,&lt;br&gt;
claude-mem and Letta, and concluded that it was missing nothing. That was a comparison of pieces:&lt;br&gt;
this is equivalent to that. The other comparison was missing, the one their benchmarks make. Given&lt;br&gt;
a question, does the line that answers it reach the agent's view, and how many tokens did it cost&lt;br&gt;
to bring it? This article is that measurement.&lt;/p&gt;

&lt;p&gt;The short version&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;With the right note in hand, reading its state and one section found the answer in 32 % of
the questions with 2.7k tokens. No number of loose fragments reached that, even with three
times the budget.&lt;/li&gt;
&lt;li&gt;The search puts the answer's note first only one time in three. With that routing, the
ladder loses by a small margin against fragments.&lt;/li&gt;
&lt;li&gt;The current state is always found; the dated history, one time in five. And half of the
answers were in the history.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The 76 % hit rate I published before measured something else: whether some useful note was&lt;br&gt;
opened, not whether the fact arrived.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;32 %&lt;/strong&gt; ladder hit rate with the right note, at 2.7k tokens&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;1 in 3&lt;/strong&gt; times the search puts the answer's note first&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;18 of 18&lt;/strong&gt; answers found when they were in the current state&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;21 of 95&lt;/strong&gt; when they were in the dated history&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What memory benchmarks measure
&lt;/h2&gt;

&lt;p&gt;LongMemEval, LoCoMo and the benchmark Mem0 publishes measure against the answer, not against the&lt;br&gt;
document: whether the evidence that answers reached the model (or whether the answer came out&lt;br&gt;
right), and how much context it cost. Mem0, for example, publishes the tokens it spends alongside&lt;br&gt;
the hit rate. Two numbers together, because loading everything always hits and is never useful. I&lt;br&gt;
measured the evidence part: whether the line that answers ended up inside what was read.&lt;/p&gt;

&lt;p&gt;My previous bench measured something else. For each message of mine, it looked at which notes&lt;br&gt;
had actually been opened to answer it and whether the search had suggested them among the top&lt;br&gt;
four. It gave 76 %. But opening a note is not finding the answer: the note can have 300 lines, and&lt;br&gt;
if the agent reads the state and the answer was in an entry from a month ago, the suggestion was&lt;br&gt;
right and the fact did not arrive.&lt;/p&gt;

&lt;h2&gt;
  
  
  A bench built from the transcripts
&lt;/h2&gt;

&lt;p&gt;I did not want to write questions by hand, because you write the ones your system answers well.&lt;br&gt;
The bench comes from the session logs that Claude Code keeps on disk. In each turn I gather the&lt;br&gt;
memory lines the agent read, and a line counts as an answer if at least three of its uncommon&lt;br&gt;
words reappear in what the agent replied and were not in my message or in the three before it. The&lt;br&gt;
second condition matters: if the word was already in the question, the match is an echo, not a&lt;br&gt;
recollection.&lt;/p&gt;

&lt;p&gt;I removed the turns where the agent writes memory, because there what it says matches the line&lt;br&gt;
since it has just drafted the line itself. I also removed each note's header, which already comes&lt;br&gt;
with the search suggestion. That left 191 pairs over 70 notes. I checked a sample of 15 by hand&lt;br&gt;
and about 12 were truly the answer: the method has noise, but it points the right way.&lt;/p&gt;

&lt;p&gt;Then each line is searched verbatim in today's notes. The ones that no longer exist are&lt;br&gt;
discarded, and that was the first odd finding: 372 lines that were answers are no longer written&lt;br&gt;
the same way, almost twice as many as remain. The notes get rewritten faster than the bench can&lt;br&gt;
stabilize. A hand-made memory bench, on a system that is edited every day, goes stale in&lt;br&gt;
weeks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four ways to read, the same budget
&lt;/h2&gt;

&lt;p&gt;On those pairs I simulated several reading policies, all of them single-pass over the current&lt;br&gt;
notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The ladder with the real routing.&lt;/strong&gt; The production search picks one or two
notes, and from each one I read the current state and the section that best fits the question,
plus the cost of the map.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The ladder with the right note given.&lt;/strong&gt; The same, but handing it the note
where the answer was. It separates the error of choosing the note from the error of choosing the
section.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loose fragments.&lt;/strong&gt; The notes are split into paragraphs (5,159) and the 5, 10,
20 or 40 that fit best are injected, without going through notes. It is the shape of Mem0 or of a
typical RAG, with one caveat: I use the same word-based search (BM25), not embeddings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Everything in context.&lt;/strong&gt; The LongMemEval baseline: it hits 100 % at a cost of
977k tokens per question.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7c32kx97wuva5o6qu7s5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7c32kx97wuva5o6qu7s5.png" alt="Scatter of hit rate against tokens read per question. Loose fragments: 7 % at 1k tokens, 14 % at 2.2k, 19 % at 4.3k and 26 % at 8.7k. Ladder with the real routing: 11 % at 3.3k and 17 % at 6.1k. Ladder with the right note given: 32 % at 2.7k." width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each point is a policy. Up and to the left is better: more answers for fewer tokens.&lt;br&gt;
191 questions, notes as of October 6, 2026.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Policy&lt;/th&gt;
&lt;th&gt;Hit rate&lt;/th&gt;
&lt;th&gt;Tokens per question&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ladder, right note given&lt;/td&gt;
&lt;td&gt;32 %&lt;/td&gt;
&lt;td&gt;2.7k&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fragments, the 40 best&lt;/td&gt;
&lt;td&gt;26 %&lt;/td&gt;
&lt;td&gt;8.7k&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fragments, the 20 best&lt;/td&gt;
&lt;td&gt;19 %&lt;/td&gt;
&lt;td&gt;4.3k&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ladder with real routing, 2 notes&lt;/td&gt;
&lt;td&gt;17 %&lt;/td&gt;
&lt;td&gt;6.1k&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fragments, the 10 best&lt;/td&gt;
&lt;td&gt;14 %&lt;/td&gt;
&lt;td&gt;2.2k&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ladder with real routing, 1 note&lt;/td&gt;
&lt;td&gt;11 %&lt;/td&gt;
&lt;td&gt;3.3k&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fragments, the 5 best&lt;/td&gt;
&lt;td&gt;7 %&lt;/td&gt;
&lt;td&gt;1.1k&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Everything in context&lt;/td&gt;
&lt;td&gt;100 %&lt;/td&gt;
&lt;td&gt;977k&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both halves are there. With the right note, the ladder is the most efficient policy in the&lt;br&gt;
table: 32 % with 2.7k tokens, against 26 % for fragments with more than three times as many. Grouping what is&lt;br&gt;
known by topic, with the current state on top, works. With the real routing, the same ladder falls&lt;br&gt;
below the fragments curve: 11 % with 3.3k, against 14 % with 2.2k.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The structure of the notes is not the problem. The problem is the step&lt;br&gt;
before: choosing which one to open. And I had measured that step with a yardstick that could not&lt;br&gt;
see the difference.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I tried two obvious fixes. One, searching inside the note for the rarest words of the question,&lt;br&gt;
which is what the agent really does when the map does not help: it gave 10 % and 15 %, no change.&lt;br&gt;
The other, routing by paragraph and then reading the note that gathered the most score, a hybrid&lt;br&gt;
of the two worlds: 7 % and 14 %. Neither moves the needle, because both depend on the same&lt;br&gt;
search.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the search fails right here
&lt;/h2&gt;

&lt;p&gt;The search puts the answer's note in first place in 32 % of these pairs, and among the top four&lt;br&gt;
suggestions in 53 %. In the previous bench, over all my messages, it gave 76 %. The difference is&lt;br&gt;
in which messages end in a fact. They are the vaguest ones: "carry on with whatever you&lt;br&gt;
recommend", "how do we move forward?", "check that everything came out right". They bring nothing&lt;br&gt;
to search with. The agent manages anyway because it has the rest of the conversation and can ask&lt;br&gt;
for another note if the first does not work, but every round trip is one more call, and every call&lt;br&gt;
re-reads the entire context.&lt;/p&gt;

&lt;p&gt;That is what this measurement does not count. The simulated policies read once and keep what&lt;br&gt;
they brought. The real agent, by construction, reached all of these answers: if not, they would&lt;br&gt;
not have made it into the bench. What the simulation shows is how much it costs to get there, not&lt;br&gt;
whether it gets there. Putting in the same table the calls the agent pays to compensate for the&lt;br&gt;
routing is what is still missing.&lt;/p&gt;

&lt;h2&gt;
  
  
  History is the weak zone
&lt;/h2&gt;

&lt;p&gt;With the right note, the ladder finds the answer depending on where it was:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxuxrgmwrsv9bcm3kzchq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxuxrgmwrsv9bcm3kzchq.png" alt="Bars: current state 100 % (18 of 18), note body 28 % (22 of 78), dated history 22 % (21 of 95)." width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ladder hit rate with the right note given, by zone of the note where the answer&lt;br&gt;
was.&lt;/p&gt;

&lt;p&gt;The current state is always read, so it always hits. History is read by section, and the&lt;br&gt;
question almost never names the date or the episode: it says "that thing from last week" or says&lt;br&gt;
nothing. LongMemEval has a category for this, temporal reasoning, and it is one of the hardest for&lt;br&gt;
the systems it evaluates. In my data half of the answers lived there.&lt;/p&gt;

&lt;p&gt;That changes how I think about the note. The current state works because it is short and gets&lt;br&gt;
rewritten: if something from the history is asked often, its place is the state, not a dated entry&lt;br&gt;
that has to be guessed. History is for auditing why something was decided, not for answering&lt;br&gt;
quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I am correcting from part two
&lt;/h2&gt;

&lt;p&gt;I wrote that the system was "already on par" with the memory projects and that word-based&lt;br&gt;
routing "was already hitting 75 %". The first was true in design and is half true in outcome: it&lt;br&gt;
wins with the right note and loses at the choice. The second measured whether a useful note was&lt;br&gt;
suggested, not whether the fact arrived. By the benchmarks' yardstick, the routing gets the note&lt;br&gt;
right in first place a third of the time.&lt;/p&gt;

&lt;p&gt;I am not changing systems because of this. Installing Mem0 or a vector database adds fixed text&lt;br&gt;
at the start of every session, which is what gets paid for most often, and the advantage of&lt;br&gt;
fragments with the real routing is a few points. The lesson is smaller and more useful: before&lt;br&gt;
saying something is on par, measure it with the same question the others ask themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  The limits, so nobody takes the numbers too far
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lexical against lexical.&lt;/strong&gt; The fragments use BM25, not embeddings, because I
do not have them installed. A semantic search could raise the fragments curve and also the
ladder's routing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A hit is not a correct answer.&lt;/strong&gt; I measure whether the line ended up inside
what was read, not whether the model used it well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A single pass.&lt;/strong&gt; The real agent compensates with calls that are not charged
here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exact match.&lt;/strong&gt; A line rewritten in other words counts as lost, so the bench
discards cases that would in practice be answered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One person.&lt;/strong&gt; These are my notes, my messages and my way of asking, which is
vague when the conversation already has context.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The script for this bench is not in the&lt;br&gt;
&lt;a href="https://github.com/talcaldeg/context-economy" rel="noopener noreferrer"&gt;context-economy&lt;/a&gt; repository, for the same&lt;br&gt;
reason as the routing one in part two: it depends on my notes reader and would not run on another&lt;br&gt;
machine. The method can be redone with what is described above, on your own transcripts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is it better to give the agent loose memory fragments, Mem0-style, or whole notes?
&lt;/h3&gt;

&lt;p&gt;In my data it depends on whether the note is chosen well. With the right note, reading its current state and&lt;br&gt;
the section that fits best found the answer in 32 % of the questions with 2.7k tokens; the&lt;br&gt;
40 best fragments reached 26 % with 8.7k. With the real routing, which gets the note right in&lt;br&gt;
first place only a third of the time, fragments win by a small margin at an equal budget.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do you build a memory test bench without writing questions by hand?
&lt;/h3&gt;

&lt;p&gt;From the transcripts. In each turn you take the memory lines the agent read, and you mark as answers the ones with at least three uncommon words that reappear in what the&lt;br&gt;
agent replied and that were not in the question. You discard the turns where the agent writes&lt;br&gt;
memory, because there the match is with what it has just drafted itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is the history of the notes the hardest zone to find?
&lt;/h3&gt;

&lt;p&gt;Because the question almost never names the date or the episode. With the right note, the current&lt;br&gt;
state was found in 18 of 18 cases and the dated history in 21 of 95. It is what LongMemEval&lt;br&gt;
calls temporal reasoning, and in my data half of the answers lived there.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Keep going.&lt;/strong&gt; This series is the basis of chapter 7 of &lt;em&gt;Claude Code en serio&lt;/em&gt;, the practical guide I am writing in Spanish. That chapter, on where the tokens go and how to bring the cost down, is a free PDF in English: &lt;a href="https://talcrafter.gumroad.com/l/claude-code-token-costs" rel="noopener noreferrer"&gt;Claude Code token costs: where they go and what works&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use it in your own setup.&lt;/strong&gt; What I learned measuring these sessions is packaged as the &lt;a href="https://talcrafter.gumroad.com/l/claude-code-cost-kit" rel="noopener noreferrer"&gt;Claude Code Cost Kit&lt;/a&gt;: seven hooks and a status line, an audit skill and a document style guard, for Windows, macOS and Linux. 29 USD, single-user license. Three of the hooks are free and open source: &lt;a href="https://github.com/talcaldeg/claude-code-cost-hooks" rel="noopener noreferrer"&gt;claude-code-cost-hooks&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://talcaldeg.github.io/articulos/memory-routing/" rel="noopener noreferrer"&gt;talcaldeg.github.io&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>llm</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Measuring was the product: almost every lever was small</title>
      <dc:creator>Tomás Alcalde</dc:creator>
      <pubDate>Tue, 13 Oct 2026 13:42:04 +0000</pubDate>
      <link>https://dev.to/talcaldeg/measuring-was-the-product-almost-every-lever-was-small-4g09</link>
      <guid>https://dev.to/talcaldeg/measuring-was-the-product-almost-every-lever-was-small-4g09</guid>
      <description>&lt;p&gt;In &lt;a href="https://talcaldeg.github.io/articulos/context-economy/" rel="noopener noreferrer"&gt;the previous article&lt;/a&gt; I explained that 94 % of what I&lt;br&gt;
spent working with a coding agent went into re-reading context, and I closed with four habits&lt;br&gt;
to bring it down. After publishing it I kept measuring. The idea was simple: take every lever&lt;br&gt;
that came up (in my notes, in forums, in what the agent-memory projects do), estimate the most&lt;br&gt;
it could possibly yield, apply it and measure again.&lt;/p&gt;

&lt;p&gt;The result is not the one I expected. Almost every lever was small. Several moved nothing. A&lt;br&gt;
couple came out negative. And the biggest correction of the month was not a technique for&lt;br&gt;
saving, but an error in the yardstick I was using to measure everything else.&lt;/p&gt;

&lt;p&gt;The short version, for anyone without twelve minutes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My meters counted every call 1.9 times. The totals in the previous article halve; its
conclusions do not change.&lt;/li&gt;
&lt;li&gt;The levers left after the first diagnosis yield, almost all of them, less than 2 % of the
spend. Abbreviating and dropping accents yield nothing.&lt;/li&gt;
&lt;li&gt;What did pay off was mechanism (a hook, a command that does three steps in one). A rule
written into the agent's instructions lasted three days.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With sessions that are already short, cutting sessions comes out negative, and sometimes&lt;br&gt;
the opposite pays: keep going in the same one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;1.9×&lt;/strong&gt; how much my meters inflated each call before I fixed them&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;3 days&lt;/strong&gt; how long a written rule lasted before it stopped being followed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&amp;lt; 2 %&lt;/strong&gt; ceiling of almost every lever measured&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;-2.7 %&lt;/strong&gt; what cutting sessions mid-task yielded&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A note on units before going on. When I say "% of the spend" I mean weighted cost, not&lt;br&gt;
volume: each kind of token is weighted by its relative price in the API, with input at 1,&lt;br&gt;
output at 5, cache reads at 0.1 and cache writes at 2 (one hour) or 1.25 (five minutes). Volume&lt;br&gt;
tells you how much was re-read; weighted cost, how much it weighs. Almost all the volume is cache&lt;br&gt;
reads and, even so, they are less than half the cost.&lt;/p&gt;
&lt;h2&gt;
  
  
  First the yardstick had to be fixed
&lt;/h2&gt;

&lt;p&gt;Mid-month, going over eight days of usage, the totals did not match the number of calls. The&lt;br&gt;
cause was trivial and had been there for weeks. Claude Code writes one line in the transcript for&lt;br&gt;
each block of the response (the text, each tool call) and repeats the same &lt;code&gt;usage&lt;/code&gt;&lt;br&gt;
block in all of them. My scripts added up lines. Each call was counted, on average, 1.9&lt;br&gt;
times.&lt;/p&gt;

&lt;p&gt;The fix was to group by &lt;code&gt;requestId&lt;/code&gt; and count once. Those eight days went from&lt;br&gt;
reporting 1,003 million tokens to 540 million. The drag from tool results fell almost by half,&lt;br&gt;
because the later turns were also being counted twice.&lt;/p&gt;

&lt;p&gt;That affects the previous article. Its absolute figures were computed with the old scripts.&lt;br&gt;
With the same window and the corrected count, the 313 sessions become 294, the 2,356 million&lt;br&gt;
tokens become 1,212, re-reading goes up from 94 % to 96 %, the curve's exponent goes from 1.20&lt;br&gt;
to 1.19, and reading whole files is still 55 % of the drag. &lt;strong&gt;The totals halved; the shape&lt;br&gt;
of the argument did not move.&lt;/strong&gt; I point it out here because those figures are still&lt;br&gt;
published, and the repository already prints the corrected ones.&lt;/p&gt;

&lt;p&gt;The second correction to the yardstick came from somewhere else. To estimate how much the&lt;br&gt;
agent's memory notes weighed, I converted characters to tokens with the rule that gets passed&lt;br&gt;
around, about 3.5 characters per token. Calibrated against my own data (the jump in context&lt;br&gt;
between two consecutive calls, which is exactly what was added), the model gave 2.1 characters&lt;br&gt;
per token for prose in Spanish. With that, memory was not 7 % of the spend, as I had calculated,&lt;br&gt;
but 10 %. The tool-result meter divided by 4, and I only fixed that on 25 September: the figures in the first part that depended on that conversion are now corrected there.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Neither correction changed a conclusion. Both changed how much each&lt;br&gt;
lever could gain, which is the only thing that helps decide which one to work on.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Measure the regime, not the history
&lt;/h2&gt;

&lt;p&gt;The second mistake was subtler. When you change something in the agent's setup (an&lt;br&gt;
instruction, a hook, a reading script), the average over the last 45 days mixes two regimes and&lt;br&gt;
describes neither.&lt;/p&gt;

&lt;p&gt;It happened to me with the memory notes. Over the full history, the diagnosis was clear: almost&lt;br&gt;
half of what was read from them was accumulated history that was not needed, and the obvious fix&lt;br&gt;
was to split each file in two, one with the current state and another with the history. But&lt;br&gt;
three days earlier I had changed the way they were read. Instead of opening the whole file, the&lt;br&gt;
agent first asked for a map of sections with the cost of each one, and then fetched only the one&lt;br&gt;
it needed. Measured only from that change, there were 2 whole-file reads against 198 by map or by&lt;br&gt;
section, and the waste of that ladder, compared with having read the whole file in that same&lt;br&gt;
session, was 1 %. Splitting files would have been work with zero return.&lt;/p&gt;

&lt;p&gt;Since then every meter accepts &lt;code&gt;--desde&lt;/code&gt; and &lt;code&gt;--hasta&lt;/code&gt; (from and to)&lt;br&gt;
with a time, and they cut by call, not by session. With both you can isolate a regime that has&lt;br&gt;
already ended and compare it with the next one. And there is a separate script,&lt;br&gt;
&lt;code&gt;regimen.py&lt;/code&gt;, that warns above the figures when the window crosses a configuration&lt;br&gt;
change.&lt;/p&gt;

&lt;p&gt;The first time I used it to check a change, the estimate missed on both sides. I had applied&lt;br&gt;
three cuts together. One of them, logging the memory notes at the end of the session with a&lt;br&gt;
single command instead of reading and editing several files, I had estimated at 0.9 points of&lt;br&gt;
the spend; it yielded 3.4 (memory writes dropped from 4.5 % to 1.1 %). Another, shrinking one&lt;br&gt;
project's instruction file to a third, promised about 8 thousand fewer tokens per call and gave&lt;br&gt;
6 thousand, with four sessions before and three after. And the total dropped 26 %, which I cannot&lt;br&gt;
attribute to anything: the new window had ten long sessions against 35 short ones in the previous&lt;br&gt;
one. The only thing that holds up when comparing windows that different is what is measured per&lt;br&gt;
call and per session on the pieces the change touched.&lt;/p&gt;
&lt;h2&gt;
  
  
  What paid off was mechanism, not text
&lt;/h2&gt;

&lt;p&gt;The big improvements of the month have something in common: none of them depends on the agent&lt;br&gt;
remembering anything. They are code that runs on its own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The cost ladder.&lt;/strong&gt; The concrete problem was a memory note of 564 lines, about 17&lt;br&gt;
thousand tokens, with 29 sections. Faced with a specific question about one of them, the only&lt;br&gt;
realistic way out was to open it whole. Two options were added to the reader: one that lists the&lt;br&gt;
sections with their line range and what each one costs, without reading any of them (about 1,200&lt;br&gt;
tokens), and another that fetches a single section (about 1,300). The principle that stuck is that&lt;br&gt;
&lt;em&gt;you see the cost before paying it&lt;/em&gt;, and that each rung is worth roughly a tenth of the&lt;br&gt;
next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blocking re-reads.&lt;/strong&gt; Auditing a month of memory reads, 47 % were of the same file&lt;br&gt;
in the same session: text that was already in the context. It was solved with a hook that denies&lt;br&gt;
the second full read of the same file. It is the only block that cannot lose information, because&lt;br&gt;
what it blocks is already loaded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Routing.&lt;/strong&gt; A hook suggests, on every message, which memory notes might help.&lt;br&gt;
It used to match the message against hand-written trigger lines; now it runs BM25 against the body&lt;br&gt;
of the notes and against the three previous messages in the session. To know whether it worked I&lt;br&gt;
built a test bench from the transcripts themselves: for each of my messages, which notes were&lt;br&gt;
actually opened to answer it. On the cases where routing is the only way in, the hit rate within&lt;br&gt;
the top four suggestions went from 41 % to 76 %, with half the tokens per message. The number&lt;br&gt;
looked too good to me, so I counted only the notes that were not in the context yet (suggesting&lt;br&gt;
one that is already open saves nothing): 68 % against 43 %. The advantage did not come from&lt;br&gt;
repeating what had already been read.&lt;/p&gt;

&lt;p&gt;That bench also corrected a figure I had taken as solid. I had written that no word-based&lt;br&gt;
routing could get past 70 % accuracy, because almost a third of the messages bring nothing to&lt;br&gt;
search with ("check that everything came out right"). I had measured it looking at each message&lt;br&gt;
on its own. With the two previous ones alongside, many of those messages do have something to&lt;br&gt;
search with, and the installed routing gets past that supposed ceiling. Where the real ceiling&lt;br&gt;
is, I do not know.&lt;/p&gt;

&lt;p&gt;And one thing I decided not to do. Fourteen notes had never been opened in 393 sessions, and&lt;br&gt;
pruning them seemed obvious. Looking at them one by one, "never opened" was not "redundant": two&lt;br&gt;
were in the index that is always loaded and work precisely without being opened, and several held&lt;br&gt;
rules that were not written anywhere else. They had not been opened because the topic had not come&lt;br&gt;
up. Deleting them meant losing knowledge to save tokens that, as long as they are not opened, cost&lt;br&gt;
nothing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Written rules wear off
&lt;/h2&gt;

&lt;p&gt;The flip side of the above. Every API call re-reads the whole context, so one extra call costs&lt;br&gt;
more than almost any file. I measured how many calls the agent made per message of mine and wrote&lt;br&gt;
an explicit rule into its instructions: chain into a single command whatever does not depend on a&lt;br&gt;
previous result, and launch independent tools together.&lt;/p&gt;

&lt;p&gt;Ten days later, calls per message had not gone down. They had doubled.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Window&lt;/th&gt;
&lt;th&gt;Mean per session&lt;/th&gt;
&lt;th&gt;Median&lt;/th&gt;
&lt;th&gt;Overall&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Before the rule&lt;/td&gt;
&lt;td&gt;18.2&lt;/td&gt;
&lt;td&gt;13.5&lt;/td&gt;
&lt;td&gt;14.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ten days with the rule written&lt;/td&gt;
&lt;td&gt;24.3&lt;/td&gt;
&lt;td&gt;19.5&lt;/td&gt;
&lt;td&gt;23.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next regime&lt;/td&gt;
&lt;td&gt;32.7&lt;/td&gt;
&lt;td&gt;27.0&lt;/td&gt;
&lt;td&gt;29.2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That number is a little misleading. Messages per session had fallen from 1.7 to 1.1: I was&lt;br&gt;
sending longer tasks in a single message. Calls per message measures the size of the task as much&lt;br&gt;
as discipline, so it works as an alarm, not as a verdict. What is comparable is the behavior the&lt;br&gt;
rule asked for. Shell commands with two or more chained steps were 84-87 % before writing it and&lt;br&gt;
86 % after: they were already chained. And calls with more than one tool rose to 47 % in the three&lt;br&gt;
days after writing the rule, only to go back to 18 % and then to 10 %. Three good days and it wore&lt;br&gt;
off. The same thing had already happened to me with another rule a few weeks earlier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F52ihx6ul6oxa5wvvhk4y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F52ihx6ul6oxa5wvvhk4y.png" alt="Bars: 9 to 16 % of calls with two or more tools before the rule, 47 % in the three days after, 18 % from September 14 and 10 % in the next regime."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Share of calls that send two or more tools together, which is what the rule asked&lt;br&gt;
for. It went up in the three days after it was written and went back to its level.&lt;/p&gt;

&lt;p&gt;I also tried the reverse mechanism: taking instructions out of the file that is always loaded&lt;br&gt;
and putting them in a file that Claude Code loads only when working on certain paths&lt;br&gt;
(&lt;code&gt;.claude/rules/&lt;/code&gt; with &lt;code&gt;paths:&lt;/code&gt;). It works, but only reading or editing with&lt;br&gt;
the file tools triggers it. If the agent reads through the shell, it does not load. Over a month,&lt;br&gt;
of the sessions that touched that folder, in 78 % the rule would not have come in. It is useful&lt;br&gt;
for reference guides tied to files that get edited, never for a rule that must not be broken.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The conclusion I drew: a written instruction yields what it yields in&lt;br&gt;
its first days, and then the usual behavior comes back. If something matters, it goes in as&lt;br&gt;
mechanism (a hook that blocks, a command that does three steps in one), not as one more line of&lt;br&gt;
instructions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  The table of small levers
&lt;/h2&gt;

&lt;p&gt;This is what the rest of the month measured. The ceiling column assumes full compliance, which&lt;br&gt;
does not exist. The cost column is what you pay for trying.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flo3vwwaczaigefaognil.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flo3vwwaczaigefaognil.png" alt="Horizontal bars: logging memory with a single command 3.4 % measured; the rest are ceilings between 2.7 % and 0.18 % of weighted cost."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The ceiling of each lever, as a percentage of weighted cost. The colored bar is the only&lt;br&gt;
one measured after applying it, and it belongs to the batch described above.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Lever&lt;/th&gt;
&lt;th&gt;Ceiling&lt;/th&gt;
&lt;th&gt;What it costs or what happened&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Batch independent reads into one call&lt;/td&gt;
&lt;td&gt;1.5-1.8 %&lt;/td&gt;
&lt;td&gt;A warning after every lone read costs 0.25 % and only breaks even at 15 % compliance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shrink tool arguments (long scripts, files written whole)&lt;/td&gt;
&lt;td&gt;2.7 %&lt;/td&gt;
&lt;td&gt;That is the total of all arguments. The "edit instead of rewrite" rule touches ~0.1 %.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load instructions by path only&lt;/td&gt;
&lt;td&gt;0.2 %&lt;/td&gt;
&lt;td&gt;Does not load if the agent reads through the shell.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trim the global instruction file&lt;/td&gt;
&lt;td&gt;0.18 % per 10 %&lt;/td&gt;
&lt;td&gt;Discarded.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split the large memory notes&lt;/td&gt;
&lt;td&gt;~1 %&lt;/td&gt;
&lt;td&gt;The ladder had already solved it.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Don't search in the wrong place (another inbox, another folder)&lt;/td&gt;
&lt;td&gt;0.25 %&lt;/td&gt;
&lt;td&gt;It is a floor. Justified by quality, not by tokens.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Locate files with a folder map instead of searching&lt;/td&gt;
&lt;td&gt;1.07 %&lt;/td&gt;
&lt;td&gt;Includes the searches that were necessary.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Abbreviate the instructions&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;4.8 % fewer characters, 0.6 % more tokens.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write without accents or ñ&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1 % more tokens.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drop the cache from one hour to five minutes&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;On a subscription, one hour is already the default.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Abbreviating deserves one more line, because it is the question I get asked most. My&lt;br&gt;
instructions are written in Spanish, and the tokenizer splits by vocabulary pieces, not by letter.&lt;br&gt;
&lt;em&gt;Que&lt;/em&gt;, &lt;em&gt;memoria&lt;/em&gt; or &lt;em&gt;después&lt;/em&gt; were already one token; &lt;em&gt;q&lt;/em&gt;,&lt;br&gt;
&lt;em&gt;mem&lt;/em&gt; or &lt;em&gt;dsp&lt;/em&gt; still cost one, and odd symbols ("c/", "x") added pieces. The&lt;br&gt;
correctly accented form turned out to be the most frequent one in the vocabulary, which is why&lt;br&gt;
stripping the accents made it more expensive. You cut by removing content, not by compressing&lt;br&gt;
it.&lt;/p&gt;

&lt;p&gt;And I mention searching in the wrong place because I was surprised at how little it weighed.&lt;br&gt;
Of 2,064 searches in two weeks, 99 failed, and I labeled them by hand one by one because the&lt;br&gt;
automatic classification confused a retry with different words with giving up. The ones that went&lt;br&gt;
to the wrong source (looking for a personal email in the work inbox, mostly) added up to 0.25 % of&lt;br&gt;
the spend, about two calls a day. It is worth fixing anyway, but because concluding "there is&lt;br&gt;
nothing" after looking in the wrong place is an error of content, not of cost.&lt;/p&gt;
&lt;h2&gt;
  
  
  Splitting sessions does not pay (and here I contradict myself)
&lt;/h2&gt;

&lt;p&gt;In the previous article the number one lever was opening a new session when changing topic. A&lt;br&gt;
month later, the measurement says that cutting mid-task comes out negative, and that sometimes the&lt;br&gt;
opposite pays.&lt;/p&gt;

&lt;p&gt;The math is this. Cutting forces you to write the session prefix to the cache again (the&lt;br&gt;
instructions, the tool definitions, what the agent needs to get started), and writing costs 2&lt;br&gt;
where reading costs 0.1. What you save is re-reading the accumulated excess on every following&lt;br&gt;
call. Cutting only pays when that excess, multiplied by the calls left, goes past about 19 times&lt;br&gt;
the size of the prefix. With sessions like mine, almost never.&lt;/p&gt;

&lt;p&gt;I simulated it on the transcripts. The rule "cut when the excess goes past 25 thousand tokens"&lt;br&gt;
gave -2.7 %; with 50 thousand, -0.6 %; from 75 thousand on it no longer cut any session. An oracle&lt;br&gt;
that cuts at the best moment, knowing the future and without paying the cost of reorienting,&lt;br&gt;
reached 2.9 %, and only in four sessions.&lt;/p&gt;

&lt;p&gt;What did pay was the reverse: carrying on with the next task in the same session when it is&lt;br&gt;
still light (under 20 thousand tokens above the floor, same folder, less than an hour between the&lt;br&gt;
two). The first day I measured it, it gave +2.2 %. Then I found that the simulation accepted&lt;br&gt;
merging sessions that had actually run in parallel, and without them it came to +1.7 to +1.9 %.&lt;br&gt;
The second day gave +0.5 %: that day the work was already chained in long sessions and there was&lt;br&gt;
hardly anywhere to merge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7slxvezmiz6iklq68soe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7slxvezmiz6iklq68soe.png" alt="Bars: cutting above 25 thousand tokens of excess -2.7 %, above 50 thousand -0.6 %, from 75 thousand 0 %; an oracle +2.9 %; merging sessions +1.7 to +1.9 % on the first day and +0.53 % on the second."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simulated savings on the transcripts, as a percentage of weighted cost. The oracle is&lt;br&gt;
an impossible ceiling: it cuts at the best moment, knows the future and does not pay the cost of&lt;br&gt;
reorienting.&lt;/p&gt;

&lt;p&gt;There is no contradiction underneath, there is a change of regime. The first article measured a&lt;br&gt;
period of sessions hundreds of turns long, where cutting saved a third. The habit worked: in the&lt;br&gt;
regime I measured, 43 of 54 sessions had a single message, with a median of 13 calls. With&lt;br&gt;
sessions that short, the margin is on the other side. I do not recommend it yet: it is two days of&lt;br&gt;
different regimes, it describes rather than recommends, and it does not measure the other cost of&lt;br&gt;
merging topics, which is the quality of what an agent answers with two matters mixed in its&lt;br&gt;
context.&lt;/p&gt;
&lt;h2&gt;
  
  
  The cache, at the prices actually paid
&lt;/h2&gt;

&lt;p&gt;In the current regime, cache reads are 46 % of weighted cost and cache writes, 36 %. Writes weigh&lt;br&gt;
more than they seem because they are paid at double price: all of them are one-hour. I wanted to&lt;br&gt;
try dropping to five minutes, which costs 1.25 instead of 2 in the API, and it turned out that on a&lt;br&gt;
subscription one hour is the default for included usage. The surcharge in my estimate was the&lt;br&gt;
API's, not what gets billed.&lt;/p&gt;

&lt;p&gt;Broken down by origin, writes were 36 % session start and 64 % new content. Rewrites due to an&lt;br&gt;
expired cache were zero in that regime. And the start is not writing the whole prefix: the first&lt;br&gt;
call reads about 42 thousand tokens from the cache, which is the prefix shared across sessions and&lt;br&gt;
survives even more than an hour without activity, and writes about 22 thousand of the session's&lt;br&gt;
own. Even so, the start weighs 14 % of the cost, because most of my sessions are short. It is the&lt;br&gt;
same math that makes cutting them negative.&lt;/p&gt;
&lt;h2&gt;
  
  
  Against the pioneers
&lt;/h2&gt;

&lt;p&gt;Mid-month I reviewed how the most cited projects handle memory, among them Anthropic's guides on context&lt;br&gt;
engineering and its memory tool, Manus (stable prefix and the file system as memory), claude-mem&lt;br&gt;
(progressive disclosure in three layers), Letta (consolidation while the agent is idle) and Mem0 and&lt;br&gt;
Zep, whose benchmarks cannot be reproduced from one harness to another.&lt;/p&gt;

&lt;p&gt;The surprise was that the system I had put together measurement by measurement was already on&lt;br&gt;
par. The routing that suggests, the section map and reading a single section are the same&lt;br&gt;
progressive disclosure as claude-mem, with the cost in view at every rung. Separating, in each&lt;br&gt;
note, a current state that gets rewritten from a history that only grows does what Zep does with&lt;br&gt;
temporal validity. I ruled out installing any of them, or a vector database: they all add fixed&lt;br&gt;
text at the start of every session, which is exactly what gets paid for most times, and the&lt;br&gt;
word-based routing was already hitting 75 %.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note from October 6, 2026: this comparison was by design. Measured by&lt;br&gt;
outcome, the way memory benchmarks measure it, the ladder wins given the right note and loses at&lt;br&gt;
picking the note, and the 75 % was measuring something else. It is in&lt;br&gt;
&lt;a href="https://talcaldeg.github.io/articulos/memory-routing/" rel="noopener noreferrer"&gt;the third part&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And with the token calibration corrected, the whole memory (instructions, index, reads, writes&lt;br&gt;
and routing) weighed 10 % of the cost, and what could be trimmed within that, between 2.5 and 3 %.&lt;br&gt;
It was applied, and it was the batch I talked about above.&lt;/p&gt;
&lt;h2&gt;
  
  
  What to measure, and with what
&lt;/h2&gt;

&lt;p&gt;If anything stuck from this month, it is the order. Before applying a lever: measure its ceiling&lt;br&gt;
with your own transcripts, assuming full compliance. If the ceiling is small, it is not even worth&lt;br&gt;
the text that explains it. If it is big, prefer a mechanism to an instruction. And after applying&lt;br&gt;
it, measure only from the moment of the change.&lt;/p&gt;

&lt;p&gt;The scripts are in &lt;a href="https://github.com/talcaldeg/context-economy" rel="noopener noreferrer"&gt;context-economy&lt;/a&gt;,&lt;br&gt;
which now has six. They read the &lt;code&gt;.jsonl&lt;/code&gt; files Claude Code leaves on disk and send&lt;br&gt;
nothing anywhere.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python medir_consumo.py &lt;span class="nt"&gt;--desde&lt;/span&gt; &lt;span class="s2"&gt;"2026-09-21 11:44"&lt;/span&gt;
python medir_tool_results.py &lt;span class="nt"&gt;--desde&lt;/span&gt; &lt;span class="s2"&gt;"2026-09-21 11:44"&lt;/span&gt; &lt;span class="nt"&gt;--top&lt;/span&gt; 25
python medir_paralelismo.py &lt;span class="nt"&gt;--desde&lt;/span&gt; &lt;span class="s2"&gt;"2026-09-21 11:44"&lt;/span&gt; &lt;span class="nt"&gt;--muestra&lt;/span&gt; pares.csv
python medir_juntar.py &lt;span class="nt"&gt;--desde&lt;/span&gt; &lt;span class="s2"&gt;"2026-09-21 11:44"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;medir_consumo.py&lt;/code&gt; gives the spend per session, with volume and weighted cost.&lt;br&gt;
&lt;code&gt;medir_tool_results.py&lt;/code&gt; ranks tool results by drag. &lt;code&gt;medir_paralelismo.py&lt;/code&gt;&lt;br&gt;
computes the ceiling of batching reads and leaves a sample to check by hand how wrong its heuristic&lt;br&gt;
is (in my case, quite: of 30 pairs it marked independent, 12 and a half were). &lt;code&gt;medir_juntar.py&lt;/code&gt;&lt;br&gt;
simulates carrying on in the same session instead of opening another. &lt;code&gt;regimen.py&lt;/code&gt; runs&lt;br&gt;
inside the others and warns if the window crosses a configuration change.&lt;/p&gt;

&lt;p&gt;There are two figures in this article that cannot be reproduced with that repository: the routing&lt;br&gt;
hit rate and the cost of searching in the wrong place. They come from two scripts that depend on my&lt;br&gt;
notes reader and on the structure of my folders, and publishing them would mean publishing something&lt;br&gt;
that does not run on another machine. What can be redone is the method, which I described above: the&lt;br&gt;
routing bench is built from your own transcripts (each message against the notes that were actually&lt;br&gt;
opened to answer it), and failed searches are detected by empty result and classified by hand. The&lt;br&gt;
session-cutting simulations and the cache breakdown are not in the repository either, since they ran&lt;br&gt;
once on one window; the session-merging one is, because I am going to repeat it.&lt;/p&gt;

&lt;p&gt;These figures belong to one person and their way of working, just as in the previous article.&lt;br&gt;
The message I take away does not depend on that. Once the first diagnosis has been applied, what is&lt;br&gt;
left to gain is small and spread out, and the only way not to spend a month on 0.2 % levers is to&lt;br&gt;
know how much each one yields before moving it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why do scripts that add up the usage block in the transcripts come out double?
&lt;/h3&gt;

&lt;p&gt;Because Claude Code writes one line per content block of each response (text, tool call) and repeats the same &lt;code&gt;usage&lt;/code&gt; in all of them. Adding up lines counted each call about 1.9 times. You have to group by &lt;code&gt;requestId&lt;/code&gt;, or by &lt;code&gt;message.id&lt;/code&gt; when it is missing, and count once.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is it better to cut the session or keep going in the same one?
&lt;/h3&gt;

&lt;p&gt;It depends on how long your sessions are today. With sessions that were already short, cutting mid-task came out negative (between -2.7 % and -0.6 % depending on the threshold), because every new session writes the prefix to the cache again. Carrying on with the next task in the same session, when it was still light, paid between +0.5 % and +1.9 % depending on the day.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does abbreviating or dropping accents save tokens?
&lt;/h3&gt;

&lt;p&gt;No. Measured on the same instruction text, written in Spanish, the abbreviated version had 4.8 % fewer characters and 0.6 % more tokens; without accents or ñ, 1 % more. The tokenizer splits by vocabulary pieces, not by letter. What moves the spend is how much text goes in and how many calls re-read it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does it work to tell the agent in its instructions to batch reads into a single call?
&lt;/h3&gt;

&lt;p&gt;It worked for three days and then wore off. Calls with two or more tools went up to 47 % and fell back to 10-18 % from the fourth day on. The ceiling was small anyway: batching every independent read would have saved between 1.5 % and 1.8 % of the spend.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Keep going.&lt;/strong&gt; This series is the basis of chapter 7 of &lt;em&gt;Claude Code en serio&lt;/em&gt;, the practical guide I am writing in Spanish. That chapter, on where the tokens go and how to bring the cost down, is a free PDF in English: &lt;a href="https://talcrafter.gumroad.com/l/claude-code-token-costs" rel="noopener noreferrer"&gt;Claude Code token costs: where they go and what works&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use it in your own setup.&lt;/strong&gt; What I learned measuring these sessions is packaged as the &lt;a href="https://talcrafter.gumroad.com/l/claude-code-cost-kit" rel="noopener noreferrer"&gt;Claude Code Cost Kit&lt;/a&gt;: seven hooks and a status line, an audit skill and a document style guard, for Windows, macOS and Linux. 29 USD, single-user license. Three of the hooks are free and open source: &lt;a href="https://github.com/talcaldeg/claude-code-cost-hooks" rel="noopener noreferrer"&gt;claude-code-cost-hooks&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://talcaldeg.github.io/articulos/small-levers/" rel="noopener noreferrer"&gt;talcaldeg.github.io&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>llm</category>
      <category>productivity</category>
    </item>
    <item>
      <title>What makes an agent expensive is not what it does, it is what it remembers</title>
      <dc:creator>Tomás Alcalde</dc:creator>
      <pubDate>Tue, 01 Sep 2026 21:04:09 +0000</pubDate>
      <link>https://dev.to/talcaldeg/what-makes-an-agent-expensive-is-not-what-it-does-it-is-what-it-remembers-24bo</link>
      <guid>https://dev.to/talcaldeg/what-makes-an-agent-expensive-is-not-what-it-does-it-is-what-it-remembers-24bo</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Correction, September 2026.&lt;/strong&gt; The scripts behind this&lt;br&gt;
article counted each model call about 1.9 times. With the corrected count, the same window gives&lt;br&gt;
294 sessions, 1,212 million tokens, 96 % re-reading and an exponent of 1.19. The totals halve&lt;br&gt;
and the diagnosis holds. What did change was the advice to cut sessions: a month later, with&lt;br&gt;
sessions already short, cutting mid-task came out negative. The details, and what I measured&lt;br&gt;
afterwards, are in &lt;a href="https://talcaldeg.github.io/articulos/small-levers/" rel="noopener noreferrer"&gt;the second part&lt;/a&gt;. A second correction, on 25 September: to go from characters to tokens I used 4 characters per token, and my data gives 2.1. That made each result about 1.9 times too small, close to how much the double count inflated the turns, so the published 380 million carry was near the mark by accident: with both fixes it is 345. The figures that depended on that conversion, and the split between short and long sessions, are now corrected in the text.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The bill started to hurt before I understood why. The work was the usual: queries against a&lt;br&gt;
production database, reports, some automation, email. Nothing that sounded expensive. But the&lt;br&gt;
consumption kept climbing and it did not match the feeling of asking for very little.&lt;/p&gt;

&lt;p&gt;So I measured it. Coding agents store every session as a &lt;code&gt;.jsonl&lt;/code&gt; file on disk,&lt;br&gt;
with the token accounting of each call to the model. They are sitting right there, for free,&lt;br&gt;
and almost nobody opens them. I wrote two scripts that read those files and answer two&lt;br&gt;
different questions: &lt;em&gt;how much did each session spend&lt;/em&gt;, and &lt;em&gt;which specific call&lt;br&gt;
inflated the context&lt;/em&gt;. What came out changed how I work, and it forced me to correct a rule&lt;br&gt;
I had written down wrong myself.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;313&lt;/strong&gt; sessions measured, the 120 days before 27 August 2026&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2.36 B&lt;/strong&gt; tokens consumed in total&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;94 %&lt;/strong&gt; of that total is re-reading context already accumulated&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0.8 %&lt;/strong&gt; is what the model actually wrote&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  First: what you pay for is not the work
&lt;/h2&gt;

&lt;p&gt;The natural intuition is that an agent costs in proportion to what it produces. It is exactly&lt;br&gt;
the other way around. Out of 2.36 billion tokens, what the model wrote (the code, the answers,&lt;br&gt;
the analysis) came to 19 million. Less than one percent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fng50fvomdvjuxz4tiu9y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fng50fvomdvjuxz4tiu9y.png" alt="Stacked bar: 94.4 % re-reading accumulated context, 4.8 % new context, 0.8 % output." width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The 2.36 billion tokens split by type. The coloured band is &lt;code&gt;cache_read&lt;/code&gt;:&lt;br&gt;
context that was already there and gets read again on every turn.&lt;/p&gt;

&lt;p&gt;The reason is structural, and it holds for any conversational agent, not just this one.&lt;br&gt;
Models have no memory between calls: on every turn the whole conversation is sent again. Turn&lt;br&gt;
40 means reading the previous 39 turns one more time. Prompt caching makes that re-reading a&lt;br&gt;
lot cheaper, but it does not remove it, and above all it does not change the fact that the&lt;br&gt;
amount grows on its own while you work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The mechanism: the same work, more expensive each time
&lt;/h2&gt;

&lt;p&gt;This is the chart that organised the diagnosis. I took the 45 sessions longer than 120&lt;br&gt;
turns, split each one into ten equal stretches, and averaged how much context the model read in&lt;br&gt;
each stretch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpauoh5pnlh19n43u924r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpauoh5pnlh19n43u924r.png" alt="Rising curve: context per turn goes from 69k in the first tenth to 200k in the last." width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Context read on each turn, by progress through the session. Average of 45 long&lt;br&gt;
sessions. The last stretch costs 2.9 times the first one, doing the same kind of work.&lt;/p&gt;

&lt;p&gt;A session starts out reading around 69 thousand tokens per turn and ends reading 200&lt;br&gt;
thousand. Nobody asked for anything bigger at the end than at the beginning. It is the same&lt;br&gt;
question, with more history behind it.&lt;/p&gt;

&lt;p&gt;Averaged over the whole curve: each turn of a long session costs close to twice what that&lt;br&gt;
same turn would cost with the session freshly started. That is the tax, and it is paid without&lt;br&gt;
ever showing up anywhere as a separate line.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I believed, and got wrong
&lt;/h2&gt;

&lt;p&gt;After the first measurement I wrote down a rule that sounded right: &lt;em&gt;cost grows with the&lt;br&gt;
square of session length&lt;/em&gt;. The reasoning was clean. If context grows linearly with turns&lt;br&gt;
and every turn re-reads all of it, the sum is quadratic. A 300-turn session should cost five&lt;br&gt;
times what four 75-turn sessions cost.&lt;/p&gt;

&lt;p&gt;When I fitted the curve against the 313 real sessions, the exponent did not come out at 2.&lt;br&gt;
It came out at 1.20.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4prv7wvczd76088ol2gw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4prv7wvczd76088ol2gw.png" alt="Log-log scatter of tokens per session against turns, with a fit of exponent 1.20 and R² 0.97." width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each dot is a session. On a log scale a power law shows up as a straight line and&lt;br&gt;
the slope is the exponent. Fit over 313 sessions, R² 0.97.&lt;/p&gt;

&lt;p&gt;The gap between 2 and 1.2 is not a blackboard detail, it changes the recommendation. At&lt;br&gt;
exponent 2, splitting one long session into ten saves 90 %. At 1.2 it saves about a third.&lt;br&gt;
Still a lot, and a third of the bill is a third of the bill, but it is a different conversation.&lt;/p&gt;

&lt;p&gt;Why did the theory overshoot? Two things it ignored. There is a large fixed floor: the first&lt;br&gt;
call of every session already starts at 59 thousand tokens on median, before you type anything,&lt;br&gt;
because the preamble with the project instructions and the tool definitions always travels.&lt;br&gt;
That floor is paid by every session, short or long, and it dilutes the part that grows. And&lt;br&gt;
long sessions do not grow forever either: they hit the context window and the history gets&lt;br&gt;
compacted.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am leaving this in because it is the part that normally does not get&lt;br&gt;
published: the rule I was applying came from correct reasoning on an incomplete assumption. The&lt;br&gt;
number corrected it. A mental model that nobody checks against their own data turns into&lt;br&gt;
technical folklore fairly quickly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where the volume comes from
&lt;/h2&gt;

&lt;p&gt;Knowing that you pay for re-reading does not tell you what to stop reading. That is what the&lt;br&gt;
second measurement is for, and it is the one that actually drives decisions.&lt;/p&gt;

&lt;p&gt;Every tool result (the contents of a file, the output of a command, an email search) enters&lt;br&gt;
the context and stays there. Its real cost is not its tokens: it is its tokens multiplied by&lt;br&gt;
the turns that came after it. A 20-thousand-token dump on turn 3 of an 80-turn session costs&lt;br&gt;
more than a 100-thousand-token one on the last turn. I call that &lt;strong&gt;carry&lt;/strong&gt;, and&lt;br&gt;
sorting by that column instead of by size completely rearranges the list of culprits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7m9964k0sfmt73w20i3m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7m9964k0sfmt73w20i3m.png" alt="Horizontal bars: reading whole files 54 %, shell commands 28 %, web and other connectors 7 %, mail and document connectors 6 %, the rest 3 %, filtered search 2 %." width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;345 million tokens of carry over the window measured, split by type of call.&lt;br&gt;
Reading whole files takes more than half.&lt;/p&gt;

&lt;p&gt;54 % is reading whole files. And inside that, the biggest surprise: a good part of it was not&lt;br&gt;
code files but &lt;strong&gt;the agent's own memory files&lt;/strong&gt;. The notes you accumulate so the&lt;br&gt;
assistant knows how the business works. Every time one of those notes becomes relevant it gets&lt;br&gt;
loaded in full, and the ones I had let grow unchecked were over 15 thousand tokens each. The&lt;br&gt;
system that existed to make the agent more efficient was the main source of variable cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern: filter before it enters, not after
&lt;/h2&gt;

&lt;p&gt;All of the above converges on a single operating rule, and it is boringly simple:&lt;br&gt;
&lt;strong&gt;whatever enters the context is paid for many times, so it has to be filtered before it&lt;br&gt;
gets in&lt;/strong&gt;. Not afterwards, not by summarising it on the next turn. Once the file is&lt;br&gt;
inside, the damage is done for the rest of the session.&lt;/p&gt;

&lt;p&gt;In practice that meant writing a thin filtered-reading layer. A reader that searches by&lt;br&gt;
regular expression with surrounding context, with a hard character cap on what reaches the&lt;br&gt;
screen and the full content dumped to a temporary file in case it is needed. It is very little&lt;br&gt;
code and has no intellectual charm whatsoever. The effect does:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Listing the last six emails&lt;/th&gt;
&lt;th&gt;tokens entering the context&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Standard mail connector&lt;/td&gt;
&lt;td&gt;5,178 (average of 171 calls)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local filtered reader&lt;/td&gt;
&lt;td&gt;495&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;An order of magnitude, for the same data on screen. And because the saving multiplies across&lt;br&gt;
every turn that comes after, in a 100-turn session that single decision is around 470 thousand&lt;br&gt;
tokens you never pay.&lt;/p&gt;

&lt;p&gt;The other three that stuck as habits, in order of how much they returned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A new session per topic.&lt;/strong&gt; By far the biggest lever, and the hardest one to
obey, because the accumulated context always looks like it is about to be useful. It almost
never is, and it is paid in full on every turn until the end. In my data, the 196 sessions of
30 turns or fewer are 67 % of all sessions and 18 % of the spend; the 20 longest take 40 %.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Large outputs go to a file, never into the conversation.&lt;/strong&gt; A report, a table
dump, a log: to disk, and into the conversation only the summary or a &lt;code&gt;head&lt;/code&gt;. I
found a single tool result of 25 thousand tokens in one turn; that poisons everything that
follows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search instead of read.&lt;/strong&gt; &lt;code&gt;grep&lt;/code&gt; with line numbers and then the
exact range, rather than opening the whole file to change three lines. Broad searches go to a
subagent, which works in its own context and returns only the conclusion.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One I evaluated and dropped: compacting the history pre-emptively at half the window. It does&lt;br&gt;
save, but it compresses exactly the fine detail (precise figures, file state) and in work with&lt;br&gt;
production data that detail is the one thing I cannot afford to lose to a mediocre summary. It&lt;br&gt;
also treats the symptom. If a session is getting heavy, ending it and opening another beats&lt;br&gt;
summarising it blind.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to measure your own
&lt;/h2&gt;

&lt;p&gt;None of this needs special instrumentation or a vendor that hands you telemetry. The&lt;br&gt;
transcripts are on your disk and they carry the &lt;code&gt;usage&lt;/code&gt; block of every call, with&lt;br&gt;
input, output and tokens read from cache. A two-hundred-line script walks them and builds the&lt;br&gt;
session ranking. Another one attributes each tool result to its call and multiplies it by the&lt;br&gt;
turns that followed.&lt;/p&gt;

&lt;p&gt;What matters is not the script but the order of the questions, and there are three:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What share of the spend is re-reading rather than producing? (If you get less than 80 %,
check the measurement.)&lt;/li&gt;
&lt;li&gt;How much does context per turn grow within a single session, start to finish? That is the
tax, and it is what decides whether cutting sessions is worth it.&lt;/li&gt;
&lt;li&gt;Which specific calls carry the most? That is your list of things to learn to read
filtered.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Mine are &lt;a href="https://github.com/talcaldeg/context-economy" rel="noopener noreferrer"&gt;in this repository&lt;/a&gt;,&lt;br&gt;
together with the script that draws these four charts. It runs with a fixed cut-off date, so the&lt;br&gt;
window is reproducible rather than drifting on every run: &lt;code&gt;python graficos_articulo.py&lt;br&gt;
--dias 120 --hasta 2026-08-27&lt;/code&gt;. None of the three is long, around two hundred lines each,&lt;br&gt;
and the questions above matter more than the code: what is worth having is the ranking of your&lt;br&gt;
own transcripts, not mine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters outside my machine
&lt;/h2&gt;

&lt;p&gt;These measurements come from one person working at a company in southern Chile. They are not&lt;br&gt;
a study. But the mechanism does not depend on scale, and the companies that started putting&lt;br&gt;
agents to real work this year are going to run into the same thing when the first bill arrives&lt;br&gt;
that does not match the intuition.&lt;/p&gt;

&lt;p&gt;What I take away is that context discipline looks far more like 1990s memory management than&lt;br&gt;
like prompt engineering. It is not about writing better instructions. It is about deciding,&lt;br&gt;
deliberately and sometimes painfully, what does &lt;em&gt;not&lt;/em&gt; get in.&lt;/p&gt;

&lt;p&gt;And about measuring it, because whoever does not measure their context ends up paying to read it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;The questions that came back after publishing this, each with the figure that answers it. All of them come from the same measurement described above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does a coding agent get more expensive as the session goes on?
&lt;/h3&gt;

&lt;p&gt;Because the model has no memory between calls: every turn resends the whole conversation. Measured across 45 long sessions, the context read per turn goes from 69 thousand tokens in the first tenth of the session to 200 thousand in the last one, doing the same kind of work. That is 2.9 times more expensive purely for carrying more history behind it.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do you cut token usage in Claude Code or any AI agent?
&lt;/h3&gt;

&lt;p&gt;Four measures, ordered by what they actually returned: start a new session when the topic changes; send large outputs to a file instead of into the conversation; use &lt;code&gt;grep&lt;/code&gt; and read the exact range rather than opening whole files; and filter what enters the context &lt;em&gt;before&lt;/em&gt; bringing it in, not by summarising it afterwards. Replacing a mail connector with a filtered local reader took the same on-screen data from 5,178 tokens down to 495.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is it better to end the session and open a new one, or keep going?
&lt;/h3&gt;

&lt;p&gt;It depends on how long your sessions run. Cost per session grows with turns raised to 1.20 (fit over 313 sessions, R² 0.97): with sessions of hundreds of turns, like the ones in this measurement, splitting them saved around a third. With sessions that are already short the sum flips, because every new session writes the instruction prefix to the cache again: in &lt;a href="https://talcaldeg.github.io/articulos/small-levers/" rel="noopener noreferrer"&gt;the September measurement&lt;/a&gt;, cutting mid-task came out between -2.7 % and -0.6 %. Also beware the rule of thumb that growth is quadratic: an exponent of 2 would promise 90 %, and against real data the exponent is not 2.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does prompt caching not solve this?
&lt;/h3&gt;

&lt;p&gt;It makes it cheaper, it does not remove it. In the measurement, 94 % of the tokens measured is &lt;code&gt;cache_read&lt;/code&gt;: context that was already there and gets read again every turn. Caching lowers the unit price, but it does not change the fact that the volume grows on its own while you work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do the agent's memory files help, or do they cost?
&lt;/h3&gt;

&lt;p&gt;Both, and it has to be measured. Reading whole files accounts for 54 % of the carry, and much of it was not source code but the agent's own memory notes: each one loads in full whenever it becomes relevant, and the ones left to grow unchecked were over 15 thousand tokens each. Split them into sections and read only the section you need.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do you measure where an agent's tokens go, without vendor telemetry?
&lt;/h3&gt;

&lt;p&gt;The transcripts are on your own disk as &lt;code&gt;.jsonl&lt;/code&gt; files, carrying the &lt;code&gt;usage&lt;/code&gt; block of every call with input, output and cache-read tokens. A script of about two hundred lines builds the session ranking; another attributes each tool result to its call and multiplies it by the turns that came after, which is the &lt;strong&gt;carry&lt;/strong&gt;. All three are published in &lt;a href="https://github.com/talcaldeg/context-economy" rel="noopener noreferrer"&gt;context-economy&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Keep going.&lt;/strong&gt; This series is the basis of chapter 7 of &lt;em&gt;Claude Code en serio&lt;/em&gt;, the practical guide I am writing in Spanish. That chapter, on where the tokens go and how to bring the cost down, is a free PDF in English: &lt;a href="https://talcrafter.gumroad.com/l/claude-code-token-costs" rel="noopener noreferrer"&gt;Claude Code token costs: where they go and what works&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use it in your own setup.&lt;/strong&gt; What I learned measuring these sessions is packaged as the &lt;a href="https://talcrafter.gumroad.com/l/claude-code-cost-kit" rel="noopener noreferrer"&gt;Claude Code Cost Kit&lt;/a&gt;: seven hooks and a status line, an audit skill and a document style guard, for Windows, macOS and Linux. 29 USD, single-user license. Three of the hooks are free and open source: &lt;a href="https://github.com/talcaldeg/claude-code-cost-hooks" rel="noopener noreferrer"&gt;claude-code-cost-hooks&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://talcaldeg.github.io/articulos/context-economy/" rel="noopener noreferrer"&gt;talcaldeg.github.io&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>llm</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
