Trail content
8 minEnglish narration, Portuguese subtitlesPodcast (RSS)
Chapters
  1. 0:00Opening
  2. 0:55The diagnosis
  3. 1:50Why it happens
  4. 2:42What it costs
  5. 3:51A challenge
  6. 4:26The treatment
  7. 5:47A coding agent
  8. 6:33Close relatives
  9. 6:59When to ignore
  10. 7:28Wrap-up
Transcript

Opening

A math tutor has been working with a student for twelve lessons. All of it in the same conversation.

In lesson one, she asked: don't show me the solution, just hints. Deal, said the tutor.

In lesson six, for a review sheet, she asked the opposite. For this sheet, you can show the full solution.

Now it's lesson twelve, and the history is almost ninety thousand tokens. She asks for help with question four. And the tutor switches between the two rules, with no clear logic.

Nobody told the tutor that the lesson six rule applied only to that sheet. Nobody summarized what the student has already mastered. The model gets everything, and tries to guess what still holds. In this lesson, you'll learn to recognize this smell, and what to put in place of an ever growing history.

The diagnosis

Here's the cycle. A new turn arrives.

Code appends it to the full history, which never shrinks.

The model reads tens of thousands of tokens, most of them irrelevant, or stale.

The answer gets worse, and costs more. And it goes into the history too, so the cycle continues.

How do you spot it? The conversation, or the agent session, only grows. Nothing ever leaves.

The model cites old information as if it were current. An order from three months ago, a file that has since changed.

Instructions given at the start get ignored, or mixed with later ones.

Cost per turn climbs through the session, even for short questions. And so does the time until the first word appears.

And answer quality drops in long sessions, while it's fine in short ones.

Why it happens

The default examples just append. The simplest chat code keeps the message list, and sends it all again. It works for the first ten turns.

Large windows feel safe. If a million tokens fit, there seems to be no reason to cut. But fitting isn't the same as being used well. Models use what sits in the middle of a long context less reliably. And the lesson one and lesson six instructions fight in exactly that middle. The window fits. Attention doesn't.

Deleting is scary. Without knowing what matters, keeping everything feels safer.

And agents produce a lot of text. Tool results, files they read, test output. All of it enters the history, and stays there, long after it stopped being useful.

What it costs

The cost starts with quality. Rules and facts buried in the middle are followed less reliably, and contradictory information produces unstable answers.

Then money, with illustrative numbers. A system prompt of two thousand tokens, and four hundred more each turn. At turn three, a call sends about three thousand two hundred tokens. At turn twelve, about six thousand eight hundred. At turn forty, about eighteen thousand.

The student's question fits in one line. The bill doesn't. Prompt caching makes a stable prefix cheaper, but history that changes every turn doesn't sit in that cached prefix. And at some point the session overflows the window, and the cut happens in the worst place, with no logic at all.

The same thing shows up in a bank's WhatsApp support. In month one, the customer mentioned a cancelled instant payment. In month three, they ask for their balance, and the bot still talks about that payment as the current problem. The new message was twelve words. The context held months of support.

A challenge

Here's one for you. A support chat always sends only the last ten messages, and drops the rest. Now customers complain that the bot forgets the order number they gave at the start. Is that context rot?

No. The context isn't rotten, it's too short. Cutting by a fixed window fixes the cost, but loses facts. What's missing is explicit conversation state, a short term memory. The order number belongs there, outside the raw history, where your code keeps it up to date.

The treatment

There are two refactorings. When the session is a long conversation, replace the history with a summary. Old turns become a summary, and facts that must last, like preferences and agreed rules, move into explicit state.

And when the context bloats with reading work, like files, pages or logs, extract a subagent. It reads in a clean context, and returns only the conclusion.

Here's lesson twelve, before and after. Before, ninety thousand tokens of raw chat, with two rules in conflict, buried in the middle. After, a short summary, the state, with the student's level and the current rule, and the most recent turns. The active rule lives in one field, that you can read, edit and test.

And watch for one mistake when you start cutting. Say you summarize every twenty turns. In month three, the summary still says: customer with a cancelled payment, treat as urgent. And the bot talks about it again, when the customer only asked for their balance. You only compacted the rot. A summary needs validity. What holds now goes into state, with a lifetime. And the past stays in the summary as past, or it leaves.

A coding agent

One more, from the agent world. A coding agent read forty files, found the cause of a bug, and is now writing the patch. All forty files still go out on every turn. What's the most useful next step?

Clear the old tool results, or move the reading into a subagent that returns only the conclusion. The files have done their job. Now they push the patch instruction into the middle of the context, where the model reads it worse. A bigger window doesn't fix that. And telling the model to ignore the files it won't use competes with tens of thousands of tokens that are still there. Code has to drop what's unused. Not the model.

Close relatives

And one case that looks similar, but isn't. A system prompt of eight thousand tokens, that never changes between turns, in conversations of about six turns. Cost per message is high. But the context doesn't grow during the session. The weight is fixed in the prompt. That's prompt bloat. Trim the prompt, and if the start is stable, cache it.

When to ignore

When can you ignore it? Sessions that are short by nature. A support chat that lasts five turns doesn't need compaction.

Tasks where the whole input is the document. Reviewing one contract at once is different from carrying an old conversation. There, the text is the work, not leftover turns.

And a prototype. Appending everything is the fastest way to test an idea. Just don't ship long sessions that way.

Wrap-up

So here's the idea to take with you. A long history isn't memory. It's a pile the model has to dig through on every turn, and pay for. Keep the facts that must last in explicit state, summarize the past as past, and let finished work leave the context.

In the next lesson, we'll do the first refactoring step by step: replace history with summary. See you there.

SmellBloaters

Context Rot

Contexto Podre

Context Rot is an AI code smell, a sign of trouble in LLM systems, in the Bloaters group. A long session drags old history that confuses the model and makes every turn pricier.

Element
03/37
Level
Intermediate
Read
4 min
Updated
On this page 7
  1. 01Signs and symptoms
  2. 02Reasons
  3. 03Cost of ignoring
  4. 04Treatment
  5. 05Payoff
  6. 06When to ignore
  7. 07Is it this smell?
  8. ··Quick answers

Signs and symptoms

A math tutor has been working with a student for twelve lessons. Everything is in the same conversation. In lesson 1 she asked: “don’t show me the solution, just hints”. In lesson 6 she asked the opposite for a review sheet: “now you can show the full solution”. By lesson 12 the history is almost 90,000 tokens long, and the tutor switches between the two rules with no clear logic.

An excerpt of the context sent in lesson 12 (anonymized and trimmed):

[lesson 1]  student: don't show me the solution, just hints
[lesson 1]  tutor: deal
            ... [312 messages] ...
[lesson 6]  student: for this sheet you can show the full solution
            ... [540 messages] ...
[lesson 12] student: can you help me with question 4?

Nobody told the tutor that the lesson 6 rule applied only to that sheet. Nobody summarized what the student has already mastered. The model gets everything and tries to guess what still holds.

Signs of Context Rot:

  • The conversation or agent session only grows; nothing ever leaves the context.
  • The model cites old information as if it were current (an order from three months ago, a file that has since changed).
  • Instructions given at the start of the session get ignored or mixed with later ones.
  • Cost per turn climbs through the session, even for short questions.
  • Time to first token climbs too.
  • Answer quality drops in long sessions and is fine in short ones.
flowchart LR
  T1(["1. New turn"]):::io --> H[("2. Entire history")]:::store
  H --> M(["3. Model"]):::llm
  M --> R(["4. Confused, expensive answer"]):::io
  R --> H
  1. Each new turn arrives.
  2. Code appends it to the full history, which never shrinks.
  3. The model reads tens of thousands of tokens, most of them irrelevant or stale.
  4. The answer gets worse and costs more. It also goes into the history, and the cycle continues.
Check +20 XP on first tryYour support bot's cost per message doubled between turn 3 and turn 40, and customer questions stay short. What do you look at first?

Reasons

  • SDK defaults append. The simplest chat example keeps the message list and sends it all again. It works for the first ten turns.
  • Large windows feel safe. If a million tokens fit, there seems to be no reason to cut. Fitting does not mean being used well.
  • Deleting is scary. Without knowing what matters, keeping everything feels safer.
  • Agents produce a lot of text. Tool results, files read, and test output enter the history and stay there long after they stopped being useful.

The paper “Lost in the Middle” (Liu et al., 2023) showed that models use material in the middle of a long context less reliably. The lesson 1 and lesson 6 instructions fight in exactly that middle. The window fits. Attention does not.

Cost of ignoring

  • Quality. Models follow instructions and facts buried in the middle of long contexts less reliably, and contradictory information produces unstable answers.
  • Money. Input cost grows every turn. A long session costs far more per question than a short one.
  • Latency. Time to first token rises with the context.
  • Limits. At some point the session overflows the window, and the cut happens in the worst place, with no logic.

A back-of-the-envelope curve

The numbers below are illustrative. Suppose a 2,000-token system prompt and 400 tokens added per turn (message plus answer).

Turn Tokens sent on that call
3 about 3,200
12 about 6,800
40 about 18,000

The student’s question in lesson 12 fits in one line. The bill does not. Prompt caching cheapens a stable prefix, but history that changes every turn does not sit in that cached prefix.

The same pattern shows up in a Brazilian bank’s WhatsApp: the customer mentioned a cancelled Pix (instant payment) in month 1, and in month 3 the bot still cites that Pix as the current problem. The new message was 12 words. The context held months of support.

Treatment

Refactoring Choose it when
Replace History with Summary The session is a long conversation. Old turns become a summary, and facts that must last (preferences, agreed rules) move to explicit state. Target: Context Compaction.
Extract Subagent The context bloats with reading work: files, pages, logs. A subagent reads in a clean context and returns only the conclusion, as in Context Isolation.

Two common mistakes when you start cutting:

  1. A fixed window of the last N messages. Cost drops, but the order number given at the start disappears. Facts that must last do not live in raw history: they live in conversation state that you update.
  2. A summary that never revisits what went stale. If the summary still carries “Pix cancelled in month 1” as an active fact, you only compacted the rot. A summary needs validity: what holds now, what is history.

Before and after, in lesson 12:

Before After
Sent to the model 90,000 tokens of raw chat short summary + state (level, current rule) + recent turns
Active rule two, in conflict, in the middle of the context one, in state: “on this sheet, show the solution”
Stable preference mixed into history an explicit field you can read, edit, and test
Check +20 XP on first tryA coding agent read 40 files, found the bug's cause, and is now writing the patch. All 40 contents still go out on every turn. What is the most useful next step?

Payoff

  • Answers that respect what holds now, not what held twelve lessons ago.
  • Stable cost per turn across the session.
  • Predictable latency.
  • Rules and preferences stored somewhere you can read, edit, and test.

When to ignore

  • Sessions that are short by nature. A support chat that lasts five turns does not need compaction.
  • Tasks where the whole input is the document. Reviewing one contract at once is different from carrying an old conversation. There the text is the work, not leftover turns.
  • Prototype. Appending everything is the fastest way to test an idea. Just do not ship long sessions that way.

Is it this smell?

Check +20 XP on first tryA coding agent reads 40 files to understand a bug. After finding the cause, it still carries all 40 files on every turn while writing the fix. Is this Context Rot?

Check +20 XP on first tryA support chat always sends the last 10 messages and drops the rest. Customers complain the bot forgets the order number they gave at the start. What is the problem?

Check +20 XP on first tryThe system prompt is 8,000 tokens and does not change between turns. Each conversation averages 6 turns. Cost per message is high. Is this Context Rot?

Check +20 XP on first tryYou started summarizing every 20 turns. The summary still says 'customer with a cancelled Pix, treat as urgent', from a month-1 case. In month 3 the customer asks for their balance. The bot talks about the cancelled Pix. What failed?

Quick answers

What is Context Rot?

Context Rot is an AI code smell, a sign of trouble in LLM systems, in the Bloaters group. A long session drags old history that confuses the model and makes every turn pricier.

How do you fix Context Rot?

With Replace History with Summary and Extract Subagent. Each refactoring has safe step-by-step mechanics with an eval before and after.

Where does Context Rot show up in practice?

In the real-world scenarios Support bot with human escalation, Coding agent, Conversational onboarding, and Educational tutor.

Go further

Relations

Part of the tracks 1
Search