Codex now remembers across sessions. Decide what it's allowed to learn before it learns the wrong thing
Codex's local memories have eleven config keys and one feature flag. Here's a conservative setup, a per-chat switch, and a script that scans the memory store for secrets.

Codex can now carry things it learned in one session into the next. That’s useful when the thing it learned is “this repo runs xUnit through dotnet test”, and expensive when it’s “the staging password is hunter2” or a workaround from a branch that was deleted a month ago. Memories are a recall layer that nobody reviews, which is a reason to configure them on purpose rather than accept whatever your install shipped with.
The settings are all documented, and most people won’t touch any of them. This is the short tour of the ones worth touching, a setup that suits a team repo, and a small script that checks what has actually been written to disk.
First, find out whether you have them
The documentation and the release notes don’t quite agree. The Codex configuration reference lists features.memories as off by default. The CLI changelog for 0.165.0, released on 27 October 2026, says Memory v2 is enabled by default for fresh profiles. Both can be true if “fresh profile” and “the flag” mean different things, but the pages don’t spell that out.
So don’t assume. Open an interactive session and run /memories. If the command exists and shows state for the current chat, the feature is live for you. Then pin the answer in your own config instead of depending on a default that has already moved once:
# ~/.codex/config.toml
[features]
memories = true
Set it to false if you’d rather not have the feature at all. Either way, the value is now yours rather than the release’s.
What gets remembered, and when
Codex doesn’t write a memory at the end of every chat. According to the docs, it skips active or short-lived sessions, waits until a chat has been idle long enough, and does the work in the background. Secrets are redacted from the generated memory fields, though the docs still tell you not to store secrets in memories and to review the files before sharing your Codex home directory.
The defaults from the configuration reference show how cautious or loose that pipeline is:
| Key | Default | What it controls |
|---|---|---|
memories.generate_memories | true | Whether new threads can become inputs to memory generation |
memories.use_memories | true | Whether existing memories are injected into future sessions |
memories.disable_on_external_context | false | Whether threads that used MCP tools, web search or tool search are excluded |
memories.min_rollout_idle_hours | 6 | Idle time before a thread is considered (allowed range 1 to 48) |
memories.max_rollout_age_days | 30 | Oldest thread considered for generation (0 to 90) |
memories.max_unused_days | 30 | Days without use before a memory is ineligible for consolidation (0 to 365) |
memories.min_rate_limit_remaining_percent | 25 | Rate-limit headroom required before generation starts (0 to 100) |
memories.max_rollouts_per_startup | 16 | Threads processed per startup pass (cap 128) |
memories.max_raw_memories_for_consolidation | 256 | Recent raw memories kept for consolidation (cap 4096) |
There are two more, memories.extract_model and memories.consolidation_model, which override the model used for per-thread extraction and global consolidation. They have no stated default, so leave them alone unless you’ve got a cost reason to move them.
The read and write switches are separate
generate_memories and use_memories are independent, and that gives you four modes. Two of them are worth knowing about.
Write on, read off: Codex keeps building a memory store but never injects it. Every session behaves as if it were the first, which is exactly what you want when you’re comparing prompts or debugging why an agent did something odd. The store keeps growing in the background, so you can flip reading back on later.
Write off, read on: Codex uses what it already has and stops learning. This suits a shared or long-lived machine where the current memory is good and you don’t want more of it. The store can only go stale from here, so it’s a holding pattern, not a destination.
[memories]
generate_memories = false
use_memories = true
A conservative setup for a team repo
Here’s a configuration that favours predictability over convenience. It turns memories on, keeps tool-assisted chats out of the store, and makes the pipeline slower to learn from anything half-finished.
# ~/.codex/config.toml
[features]
memories = true
[memories]
generate_memories = true
use_memories = true
disable_on_external_context = true
min_rollout_idle_hours = 24
max_rollout_age_days = 14
max_unused_days = 14
Each line earns its place for a reason.
disable_on_external_context = true excludes any thread that touched MCP tools, web search or tool search. The docs describe what the flag excludes, not why you’d want it, so what follows is opinion: those are the threads where text from outside your repo has been in the agent’s context, and a summary built from that text is the likeliest route for a bad instruction to outlive the session that carried it. The older name memories.no_memories_if_mcp_or_web_search still works as an alias if you’ve seen it in someone’s dotfiles.
min_rollout_idle_hours = 24 pushes the idle threshold from 6 hours to 24, so a chat you pick up again after lunch isn’t summarised halfway through the work. The documented range is 1 to 48.
max_rollout_age_days = 14 and max_unused_days = 14 halve the 30-day windows. Memories about a codebase rot faster than memories about a person, because the codebase has a merge queue. Shortening both means a convention you retired two weeks ago stops being offered as fact. The trade is that Codex forgets slow-burning project knowledge sooner, so if you work in two-month cycles, leave these at the defaults.
One more setting matters if you run on a plan with usage limits. min_rate_limit_remaining_percent defaults to 25, which means generation doesn’t start when you’ve got less than a quarter of your window left. That’s a sensible brake. Lower it only if you’d rather spend the last of your budget on memory work than on the next session.
Turn it off for one chat
The /memories command works per chat and doesn’t touch global settings. Per the docs, it controls two things for the current conversation: whether the chat can use existing memories, and whether it can contribute to future ones. It’s available in the desktop app, the TUI and interactive CLI sessions.
Use it when you’re about to paste something you don’t want summarised: a production log, a customer’s data, a one-off credential for a script. Switching the chat’s contribution off beats trusting redaction to catch every shape of secret.
Keep the rules somewhere else
The docs are blunt about this: memories are a “helpful recall layer, not as the only source for rules that must always apply”, and required team guidance belongs in AGENTS.md or checked-in docs. That’s the line to hold. Anything that would be a defect if Codex forgot it, such as the test command, the banned dependency or the migration freeze, goes in the repo. Memory is for the things that would only be annoying to rediscover.
It also means a teammate with a different memory store gets the same behaviour on the rules that matter. A checked-in rule applies to everyone who clones the repo. A memory applies to one machine.
Audit what’s on disk
Memory files live under ~/.codex/memories/, or under $CODEX_HOME/memories/ if you’ve moved the Codex home directory. The docs call them generated state: fine to inspect, not meant to be hand-edited. They hold summaries, durable entries, recent inputs and supporting evidence.
Redaction is applied to generated fields, and the documentation still says to review the files. This script does a cheap version of that review. It walks the store, prints each file’s age and size, and flags anything that looks like a credential. It exits with 1 if it finds one, so you can run it from a cron job or a pre-share check.
import os, re, sys, time
from pathlib import Path
home = Path(os.environ.get("CODEX_HOME", Path.home() / ".codex"))
root = home / "memories"
patterns = {
"aws key": re.compile(r"AKIA[0-9A-Z]{16}"),
"bearer token": re.compile(r"(?i)bearer\s+[a-z0-9._-]{20,}"),
"private key": re.compile(r"-----BEGIN [A-Z ]*PRIVATE KEY-----"),
"password assignment": re.compile(r"(?i)(password|secret|token)\s*[=:]\s*\S{8,}"),
}
if not root.is_dir():
sys.exit(f"no memory directory at {root}")
hits = 0
for path in sorted(p for p in root.rglob("*") if p.is_file()):
age = (time.time() - path.stat().st_mtime) / 86400
text = path.read_text(errors="replace")
found = [name for name, rx in patterns.items() if rx.search(text)]
flag = " <-- " + ", ".join(found) if found else ""
hits += bool(found)
print(f"{age:6.1f}d {len(text):7d} chars {path.relative_to(root)}{flag}")
sys.exit(1 if hits else 0)
Point it at a directory holding one clean file and one with a planted password = hunter2hunter2 line, and it prints:
0.0d 39 chars entries.md <-- password assignment
0.0d 34 chars summary.md
The exit code is 1. The script doesn’t know Codex’s file layout; it treats everything under memories/ as text, which is why it’s a scanner and not a parser. The patterns are deliberately crude, so expect misses on anything that isn’t one of those four shapes.
If it flags something real, the documented reset is Settings > Personalization > Delete Codex memories in the desktop app, which clears the selected machine’s store. The docs don’t describe a CLI command for it.
Isolate memory for unattended runs
CODEX_HOME is documented as the way to move the Codex home directory, and the memory files live inside it. Pointing a scripted codex exec job at its own CODEX_HOME should therefore give it its own empty memory store, so a nightly job doesn’t inherit your interactive habits and doesn’t write its own into your store. That conclusion is an inference from two documented facts, not something the memories page promises, so check it with the audit script: run the job, then run the script with CODEX_HOME set to the job’s directory and see where files land.
More generally, nothing here has been run against a live Codex build. The settings above are written from the configuration reference and the memories page, and defaults can change between releases, as the 0.165.0 note shows.
When not to bother
Skip all of this if you work in a single repo with a thorough AGENTS.md and rarely return to old chats. The memory store will mostly hold what the file already says. If you’re in a regulated environment, the simplest policy is features.memories = false in the config you ship, plus the audit script in CI for any machine that has ever had it on.
Try it now
Run /memories in an interactive session, add features.memories to config.toml with the value you actually want, and run the audit script once against ~/.codex/memories/. If it flags nothing and the files are small, leave the defaults. If it flags something, delete the store and turn on disable_on_external_context before the next session.