Is Your Agent's Memory Worth Its Tokens?

Adham Sersour
1 min read
Is Your Agent's Memory Worth Its Tokens?

Agent memory is often measured against a weak baseline. Give a plain agent the same token budget and the advantage mostly disappears into seed variance. Here is a small, reproducible experiment on a local model, and the measurement discipline it teaches.

Agent Memory

A memory module lifts your agent's benchmark score, so you ship it. But did anyone check whether a plain agent, given the same token budget, would have scored just as well? That one missing control changes what the numbers actually prove. Here is a small experiment you can run on your own machine.

🎯 The benchmark that skipped a control

Agent memory has become the obvious upgrade. You give the agent a place to store what it learned, it recalls a relevant workflow next time, and the success rate on your benchmark goes up. The benchmark number goes up, and the upgrade looks obvious.

Memory is not free. Every workflow the agent stores and re-injects into its prompt costs tokens on the next step, and those tokens are no longer available for fresh reasoning. So the fair comparison is not "agent" versus "agent plus memory". It is "agent" versus "agent plus memory, both working under the same token budget". Most benchmarks never impose that budget, which means the memory agent quietly gets to spend more to reach its score.

I wanted to see what happens when you put the budget back. This article walks through a small, reproducible experiment on a local model, section by section, and ends with a short checklist you can apply to any memory claim you read. The runnable code lives in the GitHub repository.


🧩 What "agent memory" actually means

Before measuring it, we should agree on what we are measuring. "Memory" is an overloaded word, so let us separate the common meanings. You might wonder which one this experiment targets, so let me name it. This experiment targets procedural memory specifically.

Working memory: What already sits in the context window during a single task. This is just the prompt; nothing new to store.
Episodic memory: A log of past interactions the agent can search later. Useful, but broad.
Procedural memory: A distilled recipe for how to solve a recurring type of task, saved after a success and re-used on the next similar one. This is the kind most "agent memory" products lean on, and the kind we test here.

The mechanism we study is deliberately simple, because the point is the measurement, not the cleverness of the memory. After the agent solves a task, it saves the workflow it used. When a similar task arrives, that workflow is injected into the prompt as a hint. This mirrors the "store a solved workflow, replay it later" pattern behind popular memory modules, and the whole thing is just a few lines.

python
# After a task succeeds, store the workflow that solved it, keyed by task type.
if use_memory and ok and recipe:
    memory[task["type"]] = f"For '{task['type']}' tasks: {recipe}"

# On the next task of the same type, inject that workflow into the system prompt.
recipe = memory.get(task["type"])
if recipe:
    sys += f"\nA workflow that solved a similar task before:\n{recipe}"

To make the difference tangible, here is the same task through both agents' eyes. The question is "what is the cheapest audio item?", and both agents get the same tools and the same instructions. The only difference is the block of text at the bottom of the memory agent's prompt.

Vanilla agent sees

text
You are a tool-using shopping agent.
Tools:
  search(query) -> list matching items
  open(id)      -> full details of an item
  finish(answer)-> final answer, stop

Task: what is the cheapest audio item?
Begin.

No help. It has to discover the path itself: search "audio", open each candidate, compare prices, then answer. Every exploration step spends tokens.

Memory agent sees

text
You are a tool-using shopping agent.
Tools:
  search(query) -> list matching items
  open(id)      -> full details of an item
  finish(answer)-> final answer, stop

A workflow that solved a similar task before:
For 'cheapest_cat' tasks: search(<name>)
  -> open(<id>) -> open(<id>)
  -> finish(<the cheapest_cat>)

Task: what is the cheapest audio item?
Begin.

Same prompt plus the stored recipe: it already knows the path. But that block rides along on every step of the task, and those are the rent tokens.


⚖️ Why benchmarks flatter memory

Injecting a stored workflow adds text to every step where it applies, and that text has a price paid in prompt tokens. On a task where the agent needs room to think through several tool calls, spending part of the budget on a recalled recipe leaves less room for the reasoning itself. The clean success-rate chart never accounts for that trade.

The control in one sentence Give both agents the same number of tokens per task, and see whether memory still comes out ahead once it has to pay for the space it occupies.

In the benchmark, that control is a single running counter. Every model call adds its tokens to the total, the recalled workflow included, and once the total crosses the cap the task fails. Both agents run through the exact same gate.

python
used = 0
for _ in range(max_steps):
    if used >= budget:              # the same cap applies to both agents
        return False, used, None    # out of budget, the task is a failure
    content, toks = call(msgs, temperature, seed)
    used += toks                    # every token counts, injected memory included

Without that control, a reported gain has two possible sources that nobody has separated: the memory genuinely helped, or the memory agent simply got to spend more tokens. A budget-matched comparison forces those two apart. It is one of the most useful things you can add to a memory evaluation, and it is usually missing.


🔬 The experiment: same world, same budget

To keep this reproducible on a laptop, I kept the setup small and self-contained. I ran everything on a local model through Ollama, and the agent code uses only the Python standard library, so there is nothing to install for the core benchmark and nothing hidden behind an API.

The world: A deterministic shopping catalog of twelve products with three tools: search to find items, open to read one, and finish to submit the answer. No randomness in the environment itself.
The tasks: Ten multi-hop questions such as "what is the cheapest item in the category that contains the most expensive product?". Hard enough that a plain agent is not at 100%, so the budget actually bites.
The budget: A fixed cap of 1500 tokens per task, applied identically to both agents. Run out of budget and the task is scored as a failure.
The two agents: A vanilla agent, and a memory agent that stores each solved workflow and re-injects it on the next task of the same type.
The seeds: Five random seeds, because a single run tells you almost nothing about a stochastic system.

A result you cannot reproduce is an opinion, so here is the full protocol. Every number in this article comes from this exact configuration, and the one thing that changes between the two agents is whether memory is switched on.

Experimental protocol (materials and methods)

ElementValue
ModelQwen3.6-35B-A3B, Q8_0 quantization
RuntimeOllama, local, reasoning traces off (think: false)
HardwareApple M1 Ultra, 64 GB unified memory
Temperature0.6
Seeds5 (0 through 4)
Tasks10 multi-hop shopping questions
Token budget1,500 tokens per task, prompt plus generation
Max steps12 tool calls per task
Success criterioncorrect final answer submitted before the budget runs out
Held fixedcatalog, tasks, budget, temperature, and seeds, identical for both agents
Variedone thing only: memory on versus off

The whole experiment is condensed into one script, and the notebooks in the repository unpack it one idea at a time if you want to follow along and change things.

Reproduce it

python3 smoke.py --budget 1500 --seeds 0 1 2 3 4Same catalog, same tasks, same cap for both agents. The only thing that changes is whether memory is on.

📊 The result: the effect is smaller than the noise

Look at the means alone and memory wins: 56% against 54%. It is the kind of two-point bar-chart difference that ends up in a launch post. Now add the spread across the five seeds, using the toggle below, and watch what happens to that advantage.

Same token budget: does memory win?

Success rate over 10 tasks, local Qwen3.6-35B-A3B, budget 1500 tokens/task

25%50%75%100%54%Vanilla56%Memory

Looks like memory wins. Now add the spread across random seeds.

When I ran it, the vanilla agent ranged from 30% to 80% across seeds; the memory agent from 40% to 70%. That two-point gap in the means sits inside a swing of roughly 25 points either side of the mean. On top of that, the memory agent spent about 2% more tokens to get there, because the recalled workflows cost prompt space.

Vanilla vs memory under an identical per-task token budget (5 seeds)

Metric (same token budget)VanillaMemory
Mean success rate54%56% (+2 pts)
Spread across seeds30 to 80%40 to 70%
Mean tokens per run10,66310,871 (+2%)
What the numbers say Under a matched token budget, the memory module's effect is about ten times smaller than the run-to-run variance, and it costs slightly more tokens. On this setup, memory has not been shown to help. It has been shown to be indistinguishable from noise while charging a small premium.

✅ What actually survives the control

So is memory useless? That would be the wrong lesson. A narrower reading survives: storing more text, and hoping recall lifts a score, does not hold up under a budget-matched test. What survives is a different kind of memory, and the recent literature points the same way.

In July 2026, six new agent-memory systems were published in a single week. Not one of them reported a budget-matched comparison against a plain agent, which is exactly the gap this experiment is about. But four of the six converge on the same idea:

Serving-compute framing: One July 2026 paper grades memory on first-token latency and reuse instead of task accuracy. That is the "worth its tokens" question, measured directly.
Governed procedures over text: A second validates storing verified, governed procedures in an enterprise setting, rather than dumping more conversation history.
Auditable structure over opaque recall: A third shows a queryable, inspectable memory beating opaque embedding search over a year-long deployment.
The honest counter-example: A fourth argues the opposite (more history helps), but on user-behavior prediction rather than tool use, and still without a token budget. Worth taking seriously, then scoping precisely.

All four point to the same idea: useful memory is structured, verified, and selectively exposed, not more raw history poured into the context. A verified procedure the agent can replay deterministically earns its tokens, while an undifferentiated pile of past text, recalled on similarity, mostly does not.

A fair counter-argument

One of the six papers argues that distilling more signal from history does help, and it ships the only public code of the batch. It is a genuine counter-example, so treat it as one. Its task is predicting user behavior rather than tool-using agents, and it too reports no token budget, so it sharpens the question rather than closing it.

📋 How to judge any memory claim

The takeaway is a measurement habit, one you can apply to any claim you read. Next time you meet "our memory module lifts success rate by X%", run the claim through four questions before you believe it.

Matched against what budget?: If the memory agent is allowed more tokens, part of any gain is just the extra tokens. Fix the per-task budget for both.
Over how many seeds?: A single run hides variance. Run several seeds and report the spread, not just the mean.
How big is the spread versus the effect?: If the seed spread is larger than the reported gain, the method has not been shown to help yet.
Measured on tokens, not only accuracy?: Memory that lifts accuracy but doubles token cost may lose on any real budget. Report both axes.

None of these needs a big rig. The experiment behind this article fits in one standard-library file and runs on a laptop. The discipline is what transfers: hold the budget fixed, run several seeds, and compare the effect against the spread before you trust it.


🧭 Honest limits

This teaching benchmark does not prove that memory fails in general. It uses one small model, one synthetic tool-world, and one style of procedural memory. The absolute numbers would move with a larger model, richer tasks, or a smarter memory design.

What it does show, and what a production-scale study reported independently, is the direction and the method: under a matched budget, a plain agent is a much stronger baseline than the launch charts suggest, and variance can be much larger than the reported effect. Memory may help. You cannot know whether it does until you measure it against the right control.


📚 Sources

Everything in this article is reproducible from the GitHub repository, which holds the agent, the tool-world, the benchmark, and the progressive notebooks.

GitHub repository: agent-memory-worth-its-tokens: the runnable experiment and the four teaching notebooks.
The measurement idea: The budget-matched control mirrors what recent production-scale agent research reported independently: hold the token budget equal and the memory advantage largely evaporates.
The July 2026 memory wave: A batch of new agent-memory systems published the same week, none with a token-matched control, several converging on structured and verified memory over raw text.
React:

Comments

No comments yet. Be the first to comment!