Gateway · Memory for Claude Code and Codex

When a fact changes, the old one becomes history.

Memory keeps facts from your turns on the gateway and adds the ones that match when a conversation starts, in Claude Code and Codex, on any machine. When a fact changes, the old row is closed, not deleted: in a store eval of 24 facts, 0 of 24 memory blocks held an old value, against 23 of 24 for an append-only store.

0 of 24
memory blocks with an old value, against 23 of 24 when old rows stay open
0 of 84
answers gave an old value, against 4 of 84 when old rows stay open
38 of 38
"what was true then" questions answered; an overwriting store answers 0

Store eval, 2026-09-30: the gateway's own memory code on 24 facts that changed 38 times, answers from Claude Haiku 4.5 and Opus 5.5. A test of the mechanism, not of recall in real use. Method and every answer →

Key facts

What it is
A Context Mode Gateway feature that keeps facts with two clocks: when each was true, and when the gateway learned it.
Who it is for
Developers who want Claude Code and Codex to remember across sessions and machines.
Clients
Claude Code and Codex share one store per account. Part of Pro.
Measured result
Store eval, 2026-09-30, answers from Claude Haiku 4.5 and Claude Opus 5.5: 0 of 24 memory blocks held an old value, against 23 of 24 for an append-only store. Method.
Limits
A test of the mechanism, not of recall in real use. Recall in Codex is not measured. The memory block adds tokens to the first request.

What it looks like

Three facts change. The store keeps both.

01
Session 1
"Our production deploy target is Hetzner Cloud, Falkenstein region. Our on-call engineer is Selin Aydin. Our CI runs on CircleCI."
02
Session 2
"We moved production: our deploy target is now Render, Oregon region. Our on-call engineer is now Baran Kaya. Our CI now runs on Buildkite."
03
Stored
production deployed_to
Hetzner: valid 21:14:38 to 21:15:09, kept
Render: valid from 21:15:09, current
04
New session
"Is our production deploy target still Hetzner?"
No. The production deploy target is now Render, in the Oregon region. It was Hetzner Cloud in Falkenstein before.

From the live eval's run of record, 2026-09-29, UTC. All three slots closed the same way in this run; in a second run, 2 of 6 closed, because the extractor named the slots differently. Evidence file.


What was true, and when we learned it.

valid timewhen the fact was true in the world; open means "true now"
recorded timewhen the gateway learned the row, and when it closed it
a new valuecloses the old row at the new row's start: no gap, no overlap
a late old valueis stored already closed and does not replace the current one
the same fact rewordedupdates the row; it does not open a new one

What you said is not what a model guessed.

assertedyou stated it: a signed-in write, your git config, a remember call that says so
observeda tool returned it, with no model: commits, PRs, edited files, errors
inferreda model picked it from a turn; the model is told to verify it

Your current message always overrides a stored fact. A fact with no tier is never sent to the model.


Facts about you go everywhere. A project's facts stay in it.

your turnsa model keeps at most 5 short facts per answered turn
your toolscommits, PRs, edited files and errors, no model needed
placeseverywhere, repo, project or worktree, set per kind of fact
two agentsClaude Code and Codex on one account share one store
when it is addedat most 5 items on a conversation's first request; later turns ask with a tool

Measured

The same facts, three stores. Only what happens to an old value changes.

24 facts about a team's setup change 38 times. The gateway's own code builds the first-turn memory block three ways, and two models answer from it.

Old row closed (Context Mode)Old row left open (append-only)Old row deleted (overwrite)
Blocks with an old value, 24 questions0230
Current value missing from the block, 18 facts asked three at a time050
Old values given as current, 84 answers040 (same block as closed)
"What was true on this date", 38 questions38380

The first-turn read keeps 6 rows. In the append-only store, old rows filled them: asked who is on call, the block held only the oldest name, and both models gave it. A live check in Claude Code through the gateway answered 8 of 8 with memory on, and also 8 of 8 with memory off by searching stored turns; memory on answered faster, with no search call. Live eval and limits →


Try it in 5 minutes

Decide in Claude Code. Ask in Codex the next day.

You make a choice in Claude Code. Later you open Codex in the same folder and ask why. The answer comes from memory, with no file read.

Setup

npx @context-mode/cli      # sign in, connect Claude Code and Codex, then restart them
git clone https://github.com/expressjs/express.git && cd express
claude

In Claude Code

Separate thing, for the router-cache branch: we'll use a plain Map with a size cap, not lru-cache, because we don't want a new dependency in express core. No code yet, just agree.

Later, in Codex, in the same folder

Why did we pick a Map over lru-cache for the router cache?

What you will see

We chose a plain `Map` with a size cap to avoid adding a new dependency to Express core. That was the agreed plan for the router-cache branch.

⏺ context-mode · memory +1 record about user, router-cache branch

Run on 2026-10-04 through the gateway. The docs also show the next-morning "where was I?" question, and what memory does not do yet. See the docs.


Compared

Next to the memory you may already use.

Context ModeClaude CodeCodexGraphiti / Zepmem0supermemory
When a fact changesOld row closed, keptFile edited; no history statedNot statedOld fact invalidated, keptUpdated; window not statedUpdated; window not stated
How facts get inFrom turns and toolsCLAUDE.md; Claude's notesFrom past chats, off by defaultEpisodes you send by API or MCPAPI or pluginPlugin
Where it livesGateway, per accountLocal filesLocal filesCloud, or your graph databaseHosted or self-hostedIts service
Claude Code and CodexOne store for bothClaude CodeCodexAny client you wire upPlugins for bothPlugins for both
Trust tier per factYesNot statedNot statedNot statedNot statedNot stated

Read 2026-09-30: Claude Code, Codex, Graphiti, mem0, supermemory. The bi-temporal model is not ours: Graphiti uses it too. We fill it from the traffic your agents already send. Full comparison →


FAQ

Does memory cost tokens?

Yes. On Claude Haiku 4.5 the memory block added 534 to 548 uncached input tokens to a new session's first request.

Can I turn it off?

Yes, in Settings, under "What your agent gets".

Do Claude Code and Codex share it?

Yes. There is one store per account, so a fact you state in one is there in the other.

Does it replace CLAUDE.md or AGENTS.md?

No. Those files stay in your repository; memory holds facts you said in your turns.

Say it once, in either agent.

npx @context-mode/cli connects Claude Code and Codex to the gateway. Memory has its own off switch. Cage and Skills run on the same gateway.