The Window Isn't Memory

Every subscriber pays the same £180 and buys the same larder. The tenfold difference in what comes out is operator knowledge — and for a long time I had the right discipline for the wrong reason.

I pay a flat monthly fee for the substrate I run this business on. So does everyone else on that plan. Same model, same limits, same larder — and the gap between what two operators get out of it is not small, and it is not luck. It is the thing I’ve ended up calling ingeniculture: the situation you build around the model, rather than the model itself.

In May I wrote that the skill underneath the buzzword was context discipline: people burn their allowance in two turns and blame the model, when what they are actually paying for is synthesis they could have externalised. I still think that’s right. What I’ve since measured is that the reason I gave for it was wrong, and the correct reason points somewhere genuinely counter-intuitive.

The window is the pass, not the fridge

The thing worth getting straight first, because everything else follows from it: the model has no memory.

That sounds like a limitation and it isn’t, quite. The context window is working memory — it is the pass during service, not the walk-in fridge. Everything on it is re-read on every single fire. Not consulted, not remembered. Re-read. Caching softens the bill for that, and it does not change the shape of it.

Which means the question “what does the system know?” is the wrong question. The right one is “what is on the pass right now, and did it need to be?”

The common shape is a kitchen with every ingredient out of the fridge at once. Every document, every past decision, the whole history laid across the counter in case someone asks. It feels like diligence and it reads as thoroughness, and it is a station you cannot cook on.

What I thought that meant

Keep it small.

That’s the obvious conclusion and I ran on it for months. Externalise the knowledge, tier it, pull it when the ticket calls for it. Wiki pages carry a tier that decides whether they load at boot or wait to be summoned. A routing file works as the expediter — it knows which page answers which question, so the page itself doesn’t have to be resident to be reachable. My working memory file is capped at a hard byte limit. The kernel is a kernel and not an encyclopaedia.

All of that is still true, and I’d still build it that way. But “keep it small” turns out to be the wrong end of the telescope, and if you take it as the whole rule you will make your own bill worse.

What I measured

On 31 July I sat down and actually priced it, because I had never done more than assume.

My resident load — the context that goes in at the start of every session, before any work happens — is around 182,000 tokens on the bundle’s own estimate. That is enormous. By the logic I’d been running on, it should have been the most expensive thing about the setup.

With a one-hour cache, that prefix is written once and re-read at roughly a tenth of the input rate on every later turn in the session. It costs about seven pence a turn.

A carefully hand-assembled 20,000-token context that changes every turn — the disciplined-looking thing, the small thing — costs about eight pence a turn.

Nine times the content. Slightly cheaper.

I want to be careful about what that does and doesn’t say, because the wrong reading is expensive in a new way. It does not say hoard everything. Tiering is still what earns a page residency, and a resident page nobody arrives at is still waste — it crowds the room even when it’s cheap. What it says is that once something is resident, the money is decided by whether it looks identical to the machine on the next turn.

Why mine holds still

Here is the part I find genuinely funny, in a way that isn’t flattering to me.

The reason my resident load is affordable is not that I kept it lean. It’s that I load the same 182,000 tokens every boot, byte for byte. The bundle is generated rather than hand-written — a command rebuilds it deterministically, and nothing in it carries a timestamp, a session identifier, or a section that appears only under certain conditions.

That is what makes it cacheable. And it was never the reason I generated it. I generated it because hand-maintaining a large context file is miserable and it drifts, and I wanted one source of truth instead of a document I’d have to remember to update. The economics were a side effect of a housekeeping decision, and I didn’t find out for a year.

The failure you cannot see

This is the bit I’d want a fellow operator to take away, because it is invisible from the inside and there is no alarm for it.

Anything that varies between turns, before the cache breakpoint, invalidates the whole prefix. A date interpolated into the system prompt so the assistant “knows what day it is”. A per-session identifier for logging. A tool list assembled per user. JSON serialised without sorted keys, so identical data emits different bytes on every pass.

Any one of those and you are paying full input rate on your entire context, every turn, for the rest of the session.

Nothing tells you. There is no warning, no degraded mode, no line item reading cache missed, you have paid ten times over. The system works perfectly. The answers are good. The bill is simply bigger than it needed to be, and the operator concludes that AI is expensive at scale and starts trimming the wrong thing — usually the knowledge, which is the one part that was earning its keep.

They are not being careless. They are paying ten times for the same words, and the invoice agrees with them that everything is fine.

One more trap, while we’re counting

A related thing that cost me a wrong assumption: the same content is not the same number of tokens on every model.

Counted properly rather than estimated, that identical resident load is 200,441 tokens on one model and 144,324 on another. Twenty-eight per cent apart on tokeniser generation alone, before a single word of the content changed — which is also how I found out the 182,000 I’d been quoting myself was low.

So comparing published per-token prices across model generations will price you wrong, in the direction of whichever tokeniser happens to be greedier. Compare the cost of doing the same job. Not the price of a token.

Mise en place

None of this is a prompt technique, which is why I think it stays largely unwritten.

Prompts are the visible surface — they’re what you can screenshot, and there’s an entire genre devoted to them. I’ve written mise en place twice now and I’d still say it’s the quieter half of the subject by a distance, which is the line I’ve been carrying around in my head for a month.

But the plan buys everyone the same larder. What separates two operators on identical spend is which knowledge lives on disk instead of on the pass, which of it is tiered so it arrives only when the ticket calls for it, and whether the part that stays resident holds perfectly still between services.

That’s it. That’s the discipline. It’s unglamorous, it’s mostly filing, and it is worth more than every prompt I have ever written.

A year in, I’d put it like this: pull nothing you don’t need, and never let what you do hold change shape between boots. The first half I worked out early and wrote up in May. The second half I got by accident, kept by luck, and only understood the day I finally sat down and did the arithmetic on my own bill.

← Back to Writing