Skip to main content
Start with one question: how does the agent know the current date and time?
Follow that question and you hit the prefix cache — we’ll walk through it the way MiniMax Code (MCode for short) actually does, from the intuitive move to the final design. The earlier notes have all been about subtracting from context. 01 managed subagents, 02 moved tool definitions out, 03 handled long history, 04 said don’t make the agent sit and wait on a bash command until the prompt cache expires. Space, time, and the pause tax — all counted. This note cuts a different slice: even when requests keep coming, put the time in the wrong place and the prefix cache still dies. How does the agent know the current time

The problem: the model has no clock

Once training is done, the model has no live clock. “Commits from the last week,” “today’s schedule,” “was this file changed yesterday afternoon?” — every one of those judgments needs to know what “now” is. Without the time, it defaults to living in the year its training data ended. So if you tell it — how do you tell it?

The most direct move: inject the time into the system prompt

The most obvious answer: add one line to the system prompt (SP) — the current time, down to the second. The reason is solid. One line, a few dozen tokens — next to the full system prompt and thousands of tokens of tool definitions, it looks negligible. Working directory, platform, and shell are already in the environment block; adding a date line feels natural. A lot of harnesses take this path on the first try. We almost did — or used to think this way.

How it breaks: time changes, the whole prefix misses

The catch: time changes every turn, sometimes every second. The system prompt sits at the front of the request. Put time there, and every turn rewrites the start of the prefix. Tool definitions and history behind it, even if not a single byte moved, all miss — caches match on prefix; one byte changes at the front, and everything after is invalidated. A public side note: someone noticed that Claude Code had, for a stretch, been stuffing a per-request field into the system prompt, and a third-party provider’s cache hit rate fell close to zero. The main thread isn’t that someone else crashed — it’s that the intuitive path we would take ourselves has the same structure: one volatile field, at the front of the prefix. A date line that looks cheap, multiplied by turns and requests, and what’s expensive is the whole prefix it breaks.

So why does the prefix matter so much?

Figure 1: What costs isn't the token count — it's position When the last note talked about background tasks, we hit cache lifetime: wait too long in the foreground, the cache expires. This note is the other cut — cache hits: wrong place, and even back-to-back requests go back to full price. One conclusion is enough here: Caches match on prefix. One byte changes at the front, and everything after is invalidated. So the same content can cost wildly different amounts depending on where it sits:
  1. Content at the very front that changes every time is the most expensive. It keeps everything after it from hitting the cache. Time down to the second, if stuffed into the system prompt, invalidates the whole prefix every turn — system prompt, tool definitions, history, all recomputed with it.
  2. Content written into history and then left alone has limited impact. What you write on turn 5 is already part of the prefix by turn 6. As long as it isn’t rewritten, later turns keep hitting. The cost is mainly the first write, plus context growing turn by turn — exactly what 03 is about.
  3. Content attached only to the end of this request, never entering history, is never cached. It doesn’t break anyone else’s cache, but every send is a full-price input.
Here’s the most counterintuitive line in the note: A field of a few dozen tokens, in the wrong place, can cost more than thousands of tokens of tool definitions. However long the tool definitions are, as long as the bytes don’t change each turn, they sit steadily in the cacheable prefix — almost “buy once, use at cache price after.” Flip it around: one small field on the prefix that changes every turn sends that whole bargain back to full price in one shot. A few plain rules fall out of that:
  • Put stable content first; put changing content later. Current time doesn’t go in the system prompt; it rides along with each user message.
  • Don’t rewrite what’s already in history. If you need to adjust, only change future turns.
  • Precision that’s good enough is enough. Time down to the second is almost useless to the model, and it guarantees every copy differs from the last.
If you’re building an agent harness: tag every injected chunk with two attributes — “how often it changes” and “where it sits.” Things that change fast and sit early get handled first. The prefix cache isn’t a cost-saving easter egg; it’s a first-class design constraint.

A quick look: what’s in one request

Figure 2: In one "hi", what is the stable prefix With the rules in hand, looking at what an MCode request actually looks like makes the next section clearer:

How MCode does it now

Figure 3: Same time field — where you put it decides whether the prefix lives Flip that intuitive path around, and you get what we do now. The # Environment block in the system prompt only holds things that stay put for a session. Working directory, whether it’s a git repo, platform, shell, OS, model, locale, region, data directory — these barely change inside one session, so they sit up front and stay in the cacheable prefix. There is no current time here. In the public code this is the environment-prompt-composer family of assembly logic. Current time goes into the <agent-context> at the start of each turn’s user message. Built by buildSlimAgentContextBlock. From turn 2 on it looks roughly like this (illustrative; field values are made up):
By the previous section’s taxonomy, that’s type 2: written into history, then left alone. The time written on turn 5 is already part of the prefix by turn 6; as long as you don’t rewrite it, later turns keep hitting. The model still gets “today” and “recently,” without touching the system prompt every turn. The same time field is a disaster at the front of the prefix and only a per-turn tail when it rides with the user message — figure 3 puts the two placements side by side. Once placement is right, tighten along the same line:
  • Precision that’s good enough. #459 changes date from second precision to minute precision (formatReminderDate). Timezone and offset stay; seconds change every turn and barely help the model. After placement is right, cut “must change every turn” precision that isn’t needed.
  • Don’t rewrite what’s already in history. To adjust, only change future turns. Bytes already written into <agent-context> stay put, so the prefix you’ve built up can stand.
If you’re building an agent harness: for anything that changes, ask first whether it belongs in the system prompt. If it does, you’re trading the whole prefix for one convenient line. Move it first; then talk about precision.

Looking back

Figure 4: Five junctions on the same road Put the earlier notes side by side and they’re junctions on the same road:
  • 01: don’t manage context by piling on subagents
  • 02: load tool definitions on demand; don’t stuff them all into every turn
  • 03: compress long history when you should; put what matters into memory
  • 04: don’t make the model sit and wait — cut the “pause tax” — protecting cache lifetime
  • This note: don’t let one time field sink the prefix — protecting cache hits
03 said: the context window is a workbench, not a warehouse. This note wants to add: for the things you lay out on that workbench every day, where they sit matters more than how much there is. How does the agent know the current time? The most direct move is to stuff it into the SP; the design that holds up is to let time ride with each turn’s user message, and protect that whole stable prefix up front.

A short self-check for people building agents

These changes are all in the public MiniMax Code repo. Come read the code, file issues, throw bricks.
Curious what you’ve seen: how do you tell the agent the current time? Have you ever had a date line sink a whole prefix cache?