Why your coding agent forgets, and what to actually do about it

Why your coding agent forgets, and what to actually do about it

The agent solved this exact problem yesterday. Today it has never heard of your project, reinvents a helper you already have, and picks a different naming convention than the one it picked last time.

Short answer: an agent has no memory between sessions and a finite context window inside one. Everything it knows about your project has to be re-supplied every session, either by you, by a file it reads on startup, or by a tool it can call. Most complaints about agent quality are context problems wearing a capability costume, and the fixes are unglamorous: write the conventions down, keep the window clean, and make the codebase searchable.

A long horizontal bar representing a context window filled with labelled segments for system, files, history and tools, with an amber segment overflowing past the edge

What is actually in the window

Four things compete for the same space, and they compete every single turn.

  • System and instructions. The tool’s own prompt plus whatever project instructions it loaded. Small, stable, and the highest-leverage bytes in the whole window.
  • Tool definitions. Every tool the agent can call, with its schema. Modest per tool and surprising in aggregate once you have connected several MCP servers.
  • File contents. Whatever it has read. This is almost always the largest slice and the one that grows without anyone deciding it should.
  • Conversation history. Every turn so far, including every tool result it has already seen.

The important property: this is resent on every single request. It is not a database the model queries. It is a block of text handed over in full, each turn, and it grows monotonically until something evicts from it.

Bigger windows did not solve this

Current models take very large contexts and that genuinely helped. It did not make context management go away, for two reasons.

Attention is not uniform. Material at the start and end of a long context is used more reliably than material buried in the middle. Filling a window is not the same as the model using what is in it, and the failure is silent: you get a confident answer that ignored the file you thought you provided.

Every token is resent. A large window means a large request, every turn. That is a latency cost and a real bill, and it is the mechanism behind most surprising invoices, covered in what agents cost and where the tokens go.

A line chart showing recall quality against position in a long sequence, high at the ends and dipping deeply through the middle in amber

So the goal is not to fill the window. It is to put the right things in it, near the ends, and keep the rest out.

Why does the agent not remember yesterday?

Because there is nowhere for it to remember. The session ends, the context is discarded, and the next session starts from the system prompt.

Three things get called memory and only one of them survives a restart.

Session context. What is in the window right now. Dies with the session. This is what people usually mean and it is the least durable form.

Persistent instruction files. A file in the repository the agent reads on startup. Claude Code’s memory system works this way, and AGENTS.md is the emerging cross-tool convention for the same idea. This survives restarts, survives model changes, and is version controlled, which makes it the only form of memory that is actually reviewable.

Retrievable state. Anything the agent can go and fetch: the codebase itself, a search index, an external system behind a tool call. Unbounded and only as good as the agent’s ability to know it should look.

An isometric comparison: a tall unstable stack of loose sheets tipping over, beside a compact indexed card file with three cards raised

The lesson is blunt: if a fact matters more than once, it belongs in a file, not in a conversation. Explaining your conventions in chat works until the session ends, and then you explain them again, slightly differently, and the agent produces slightly different code.

Three fixes that actually work

One: write the conventions down, and keep them short. A project instruction file the agent reads on startup is the highest-return thing available. Short, because it is prepended to every request and a bloated one crowds out the code. There is a full treatment in writing instruction files an agent will follow, including why a 400-line one performs worse than a 60-line one.

Two: make the codebase answer questions. An agent that can grep, follow imports and read a test suite reconstructs context on demand and does not need it preloaded. This is why a well-organised repository with real tests gets better agent output than a sprawling one with the same model behind it. Clear module boundaries and honest naming are agent-legible in a way that comments are not.

Three: start a fresh session more often than feels natural. A long session accumulates dead context: files that turned out irrelevant, failed attempts, tool output from a path you abandoned. That material is still being resent and still competing for attention. Finishing a task and starting clean is usually faster than pushing through, and it is close to free.

Compaction and clearing, briefly

When a session runs long, tools deal with it in one of two ways.

Compaction summarises earlier context so the conversation can continue. Useful, lossy, and the loss is unpredictable: you do not get to choose which detail the summary drops.

Clearing removes old tool results or reasoning outright, keeping the recent turns intact. More predictable, and it discards rather than distorts.

Both are better than hitting the ceiling, and neither is better than not needing them. If you are relying on compaction to get through routine work, the real problem is upstream: too much got read that did not need reading.

Caching is why any of this is affordable

One mechanism worth knowing about because it changes how you should structure a session. Prompt caching lets the stable prefix of a request be reused across turns instead of reprocessed.

The consequence for you is a rule of thumb: stable content first, volatile content last. Instructions and tool definitions at the front, the changing question at the end. Anything that edits the front of the context invalidates the cache for everything after it, which turns a cheap turn into a full-price one. Tools handle most of this for you, but it explains why swapping your instruction file mid-session is more expensive than it looks.

The reframe

Stop treating context as a resource to fill and start treating it as a working set to curate. The question on any turn is not “does the agent have enough” but “is the thing it needs near the top”.

Almost everything else follows from that: short instruction files, fresh sessions, a searchable repository, tools that fetch rather than preload. It is also why the same model produces very different quality in two different repositories, which is the point in what an AI coding agent actually is and the reason review has to change shape when the author cannot remember writing the code.

The one context decision with the longest tail is which infrastructure the agent assumes, because that gets encoded in the repository and outlives every session: the infrastructure your agent picks for you.